OpenPrinting / cups

OpenPrinting CUPS Sources
https://openprinting.github.io/cups
Apache License 2.0
1.1k stars 195 forks source link

CUPS_DEBUG_LOG support for "%d" is not properly guarded #1066

Closed frostb1ten closed 1 week ago

frostb1ten commented 1 month ago

Description A format string vulnerability exists in CUPS when compiled with debugging enabled. The vulnerability arises from improper sanitization of the CUPS_DEBUG_LOG environment variable in the _cups_debug_set() function. Specifically, this variable is passed to snprintf() without validation, allowing user input with format specifiers (e.g., %p, %n) to be processed.

This can lead to:

This finding was originally discovered while reviewing the code at: https://github.com/OpenPrinting/cups/blob/master/cups/debug.c#L98:

 _cups_debug_set(getenv("CUPS_DEBUG_LOG"), getenv("CUPS_DEBUG_LEVEL"), getenv("CUPS_DEBUG_FILTER"), 0);

In this code, the CUPS_DEBUG_LOG environment variable is passed to the _cups_debug_set() function, which processes the environment data. The vulnerability occurs when the function then reaches the following line: https://github.com/OpenPrinting/cups/blob/master/cups/debug.c#L278:

snprintf(buffer, sizeof(buffer), logfile, getpid());

Here, snprintf() is used to format the log file string, which can lead to a format string vulnerability if user-controlled input contains specifiers like %p or %n. This allows an attacker to leak memory addresses or attempt arbitrary memory writes in environments where protections like %n blocking may not be in place.

To Reproduce Steps to reproduce the behavior:

  1. Compile CUPS with debug mode enabled:
    git clone https://github.com/OpenPrinting/cups.git
    cd cups
    ./configure --enable-debug --enable-debug-printfs --disable-shared --disable-gssapi
    make
  2. Set the CUPS_DEBUG_LOG environment variable with a format string and launch cupsd:
    mkdir /tmp/test
    export CUPS_DEBUG_LOG="/tmp/test/%p %p"
    ./scheduler/cupsd -f  # Break out of this after it starts running.
  3. Observe the output in /tmp/test2/, where the file is named using leaked memory addresses due to the %p specifiers. cca25949-59ac-43ce-904c-ccffa1ee6180

Expected behavior The CUPS_DEBUG_LOG variable should be treated as a plain string, and any format specifiers should not be interpreted by snprintf(). The log file should be created without leaking memory addresses or allowing unintended memory writes.

System Information:

michaelrsweet commented 1 month ago

Note: Not treating as a security issue because debug printfs are a developer tool that is not normally compiled into the library.

CUPS_DEBUG_LOG is defined as supporting only a single "%d" to insert the current process ID. Update the code to look for this and substitute manually rather than using snprintf to do the heavy lifting.

michaelrsweet commented 1 month ago

Oh, and thank you for finding and reporting this issue... :)

michaelrsweet commented 1 week ago

[master 0da38a5f7] Harden debug printf PID support (Issue #1066)