Merge pull request #8272 from hmac/hmac/tainted-format-string

This commit is contained in:
Harry Maclean
2022-03-22 08:37:47 +13:00
committed by GitHub
16 changed files with 345 additions and 10 deletions

View File

@@ -0,0 +1,50 @@
<!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> 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.
</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, string interpolation should be used exclusively:
</p>
<sample src="examples/tainted_format_string_interpolation.rb"/>
</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>
</references>
</qhelp>

View File

@@ -0,0 +1,21 @@
/**
* @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.DataFlow
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"

View File

@@ -0,0 +1,5 @@
class UsersController < ActionController::Base
def index
printf("Unauthorised access attempt by #{params[:user]}: %s", request.ip)
end
end

View File

@@ -0,0 +1,5 @@
class UsersController < ActionController::Base
def index
printf("Unauthorised access attempt by %s: %s", params[:user], request.ip)
end
end

View File

@@ -0,0 +1,5 @@
class UsersController < ActionController::Base
def index
puts "Unauthorised access attempt by #{params[:user]}: #{request.ip}"
end
end