A log injection vulnerability arises when a log entry contains unsanitized user input. A malicious user can insert fake log data and consequently deceive system administrators as to the system's behavior [OWASP 2008]. For example, a user might split a legitimate log entry into two log entries by entering a carriage return and line feed (CRLF) sequence, either of which might be misleading. Log injection attacks can be prevented by sanitizing and validating any untrusted input sent to a log.
Logging unsanitized user input can also result in leaking sensitive data across a trust boundary, or storing sensitive data in a manner that violates local law or regulation. For example, if a user can inject an unencrypted credit card number into a log file, the system could violate PCI DSS regulations [PCI 2010]. See rule IDS00-J for more details on input sanitization.
This noncompliant code example logs the user's login name when an invalid request is received. No input sanitization is performed.
if (loginSuccessful) {
logger.severe("User login succeeded for: " + username);
} else {
logger.severe("User login failed for: " + username);
}
|
Without sanitization, a log injection attack is possible. A standard log message when username is david might look like this:
May 15, 2011 2:19:10 PM java.util.logging.LogManager$RootLogger log SEVERE: User login failed for: david |
If the username that is used in a log message was not david, but rather a multiline string like this:
david May 15, 2011 2:25:52 PM java.util.logging.LogManager$RootLogger log SEVERE: User login succeeded for: administrator |
the log would contain the following misleading data:
May 15, 2011 2:19:10 PM java.util.logging.LogManager$RootLogger log SEVERE: User login failed for: david May 15, 2011 2:25:52 PM java.util.logging.LogManager log SEVERE: User login succeeded for: administrator |
This compliant solution sanitizes the username input before logging it, preventing injection attacks. Refer to rule IDS00-J for more details on input sanitization.
if (!Pattern.matches("[A-Za-z0-9_]+", username)) {
// Unsanitized username
logger.severe("User login failed for unauthorized user");
} else if (loginSuccessful) {
logger.severe("User login succeeded for: " + username);
} else {
logger.severe("User login failed for: " + username);
}
|
Allowing unvalidated user input to be logged can result in forging of log entries, leaking secure information, or storing sensitive data in a manner that violates a local law or regulation.
Rule |
Severity |
Likelihood |
Remediation Cost |
Priority |
Level |
|---|---|---|---|---|---|
IDS03-J |
medium |
probable |
medium |
P8 |
L2 |
<ac:structured-macro ac:name="unmigrated-wiki-markup" ac:schema-version="1" ac:macro-id="02b7fc48-8dfd-444e-b2cc-e13e72f77657"><ac:plain-text-body><![CDATA[ |
[ISO/IEC TR 24772:2010 |
http://www.aitcnet.org/isai/] |
Injection [RST] |
]]></ac:plain-text-body></ac:structured-macro> |
CWE-144. Improper neutralization of line delimiters |
||||
|
CWE-150. Improper neutralization of escape, meta, or control sequences |
<ac:structured-macro ac:name="unmigrated-wiki-markup" ac:schema-version="1" ac:macro-id="6ce41665-fc9a-4e29-881d-990f64e01984"><ac:plain-text-body><![CDATA[ |
[[API 2006 |
AA. Bibliography#API 06]] |
]]></ac:plain-text-body></ac:structured-macro> |
<ac:structured-macro ac:name="unmigrated-wiki-markup" ac:schema-version="1" ac:macro-id="c6d6da7f-8351-442d-bfb4-14e2ad74bb6b"><ac:plain-text-body><![CDATA[ |
[[OWASP 2008 |
AA. Bibliography#OWASP 08]] |
]]></ac:plain-text-body></ac:structured-macro> |
<ac:structured-macro ac:name="unmigrated-wiki-markup" ac:schema-version="1" ac:macro-id="97ed695d-7088-47a7-8583-42795d4496a9"><ac:plain-text-body><![CDATA[ |
[[PCI DSS Standard |
https://www.pcisecuritystandards.org/security_standards/pci_dss.shtml]] |
]]></ac:plain-text-body></ac:structured-macro> |
IDS02-J. Canonicalize path names before validating them IDS04-J. Limit the size of files passed to ZipInputStream