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. Sanitize untrusted data passed across a trust boundary 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 just validates the username
input before logging it, preventing injection attacks. Refer to rule IDS00-J. Sanitize untrusted data passed across a trust boundary 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 |
Tool | Version | Checker | Description |
---|---|---|---|
Klocwork | SVLOG_FORGING | Implemented | |
Fortify | Log_Forging | Implemented |
Injection [RST] | |
CWE-144. Improper neutralization of line delimiters | |
| CWE-150. Improper neutralization of escape, meta, or control sequences |
[API 2006] |