mirror of
https://github.com/github/codeql.git
synced 2025-12-24 04:36:35 +01:00
Ruby: Add rb/tainted-format-string query
This commit is contained in:
@@ -0,0 +1,51 @@
|
||||
<!DOCTYPE qhelp PUBLIC
|
||||
"-//Semmle//qhelp//EN"
|
||||
"qhelp.dtd">
|
||||
<qhelp>
|
||||
|
||||
<overview>
|
||||
<p>
|
||||
Methods like <code>Kernel.printf</code> 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.
|
||||
</p>
|
||||
</overview>
|
||||
|
||||
<recommendation>
|
||||
<p>
|
||||
Either sanitize the input before including it in the format string, or use a
|
||||
<code>%s</code> specifier in the format string, and pass the untrusted data as corresponding
|
||||
argument.
|
||||
</p>
|
||||
</recommendation>
|
||||
|
||||
<example>
|
||||
<p>
|
||||
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 <code>Kernel.printf</code> to be appended to the message:
|
||||
</p>
|
||||
<sample src="examples/tainted_format_string_bad.rb"/>
|
||||
<p>
|
||||
However, if a malicious user provides a format specified such as <code>%s</code> as their
|
||||
user name, <code>Kernel.printf</code> throw an exception that 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.
|
||||
</p>
|
||||
<p>
|
||||
Instead, the user name should be included using the <code>%s</code> specifier:
|
||||
</p>
|
||||
<sample src="examples/tainted_format_string_good.rb"/>
|
||||
|
||||
<p>
|
||||
Alternatively, a method such as <code>Kernel.puts</code> should be used, which does not
|
||||
apply string formatting to its arguments.
|
||||
</p>
|
||||
</example>
|
||||
|
||||
<references>
|
||||
<li>Ruby documentation for <a href="https://docs.ruby-lang.org/en/3.1/Kernel.html#method-i-sprintf">format strings</a>.</li>
|
||||
<li>Common Weakness Enumeration: <a href="https://cwe.mitre.org/data/definitions/134.html">CWE-134</a>.</li>
|
||||
</references>
|
||||
</qhelp>
|
||||
20
ruby/ql/src/queries/security/cwe-134/TaintedFormatString.ql
Normal file
20
ruby/ql/src/queries/security/cwe-134/TaintedFormatString.ql
Normal file
@@ -0,0 +1,20 @@
|
||||
/**
|
||||
* @name Use of externally-controlled format string
|
||||
* @description Using external input in format strings can lead to garbled output.
|
||||
* @kind path-problem
|
||||
* @problem.severity warning
|
||||
* @security-severity 7.3
|
||||
* @precision high
|
||||
* @id rb/tainted-format-string
|
||||
* @tags security
|
||||
* external/cwe/cwe-134
|
||||
*/
|
||||
|
||||
import ruby
|
||||
import codeql.ruby.security.TaintedFormatStringQuery
|
||||
import DataFlow::PathGraph
|
||||
|
||||
from Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink
|
||||
where cfg.hasFlowPath(source, sink)
|
||||
select sink.getNode(), source, sink, "$@ flows here and is used in a format string.",
|
||||
source.getNode(), "User-provided value"
|
||||
@@ -0,0 +1,5 @@
|
||||
class UsersController < ActionController::Base
|
||||
def index
|
||||
printf("Unauthorised access attempt by #{params[:user]}: %s", request.ip)
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,5 @@
|
||||
class UsersController < ActionController::Base
|
||||
def index
|
||||
printf("Unauthorised access attempt by %s: %s", params[:user], request.ip)
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user