Use of externally-controlled format string¶
ID: rb/tainted-format-string Kind: path-problem Security severity: 7.3 Severity: warning Precision: high Tags: - security - external/cwe/cwe-134 Query suites: - ruby-code-scanning.qls - ruby-security-extended.qls - ruby-security-and-quality.qls Click to see the query in the CodeQL repository
Methods like Kernel.printf accept a format string that is used to format the remaining arguments by providing inline format specifiers. If the format string contains unsanitized input from an untrusted source, then that string may contain unexpected format specifiers that cause garbled output or throw an exception.
Recommendation¶
Either sanitize the input before including it in the format string, or use a %s specifier in the format string, and pass the untrusted data as corresponding argument.
Example¶
The following program snippet logs information about an unauthorized access attempt. The log message includes the user name, and the user’s IP address is passed as an additional argument to Kernel.printf to be appended to the message:
class UsersController < ActionController::Base def index printf("Unauthorised access attempt by #{params[:user]}: %s", request.ip) end end However, if a malicious user provides a format specified such as %s as their user name, Kernel.printf will throw an exception as there are too few arguments to satisfy the format. This can result in denial of service or leaking of internal information to the attacker via a stack trace.
Instead, the user name should be included using the %s specifier:
class UsersController < ActionController::Base def index printf("Unauthorised access attempt by %s: %s", params[:user], request.ip) end end Alternatively, string interpolation should be used exclusively:
class UsersController < ActionController::Base def index puts "Unauthorised access attempt by #{params[:user]}: #{request.ip}" end end References¶
Ruby documentation for format strings.
Common Weakness Enumeration: CWE-134.