Ruby: document rb/log-injection

This commit is contained in:
Alex Ford
2022-08-10 16:17:18 +01:00
parent c31995764b
commit 00e290e1f1
3 changed files with 89 additions and 0 deletions

View File

@@ -0,0 +1,62 @@
<!DOCTYPE qhelp PUBLIC
"-//Semmle//qhelp//EN"
"qhelp.dtd">
<qhelp>
<overview>
<p>
If unsanitized user input is written to a log entry, a malicious user may
able to forge new log entries.
</p>
<p>
Forgery can occur if a user provides some input with characters that are
interpreted when the log output is displayed. If the log is displayed as a plain
text file, then new line characters can be used by a malicious user. If the log
is displayed as HTML, then arbitrary HTML may be included to spoof log entries.
</p>
</overview>
<recommendation>
<p>
User input should be suitably sanitized before it is logged. Suitable means of
sanitization depend on how the log entries will be displayed or consumed.
</p>
<p>
If the log entries are in plain text then line breaks should be removed from
user input, using <code>String#gsub</code> or similar. Care should also be
taken that user input is clearly marked in log entries.
</p>
<p>
For log entries that will be displayed in HTML, user input should be
HTML-encoded before being logged, to prevent forgery and other forms of HTML
injection.
</p>
</recommendation>
<example>
<p>
In the example, a username, provided by the user, is logged using `Logger#info`.
</p>
<p>
In the first case, it is logged without any sanitization. If a malicious user
provides `username=Guest%0a[INFO]+User:+Admin%0a` as a username parameter, the
log entry will be split in two different lines, where the second line will
be `[INFO]+User:+Admin`.
</p>
<sample src="examples/log_injection_bad.rb" />
<p>
In the second example, <code>String#gsub</code> is used to ensure no line
endings are present in the user input.
</p>
<sample src="examples/log_injection_good.rb" />
</example>
<references>
<li>OWASP: <a href="https://www.owasp.org/index.php/Log_Injection">Log Injection</a>.</li>
</references>
</qhelp>

View File

@@ -0,0 +1,13 @@
require 'logger'
class UsersController < ApplicationController
def login
logger = Logger.new STDOUT
username = params[:username]
# BAD: log message constructed with unsanitized user input
logger.info "attempting to login user: " + username
# ... login logic ...
end
end

View File

@@ -0,0 +1,14 @@
require 'logger'
class UsersController < ApplicationController
def login
logger = Logger.new STDOUT
username = params[:username]
# GOOD: log message constructed with unsanitized user input
sanitized_username = username.gsub("\n", "")
logger.info "attempting to login user: " + sanitized_username
# ... login logic ...
end
end