Skip to content

Commit e11605b

Browse files
committed
pySCG: adding 117 as part of #531
Signed-off-by: emcdtho <[email protected]>
1 parent 18c8b89 commit e11605b

File tree

4 files changed

+168
-15
lines changed

4 files changed

+168
-15
lines changed
Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
# CWE-117: Improper Output Neutralization for Logs
2+
3+
Log injection occurs when untrusted data is written to application logs without proper neutralization, allowing attackers to forge log entries or inject malicious content. Attackers can inject fake log records or hide real ones by inserting newline sequences (`\r` or `\n`), misleading auditors and incident-response teams. This vulnerability can also enable injection of XSS attacks when logs are viewed in vulnerable web applications.
4+
5+
Attackers can exploit this weakness by submitting strings containing CRLF (Carriage Return Line Feed) sequences that create fake log entries. For instance, an attacker authenticating with a crafted username can make failed login attempts appear successful in audit logs, potentially framing innocent users or hiding malicious activity.
6+
7+
This vulnerability is classified as **CWE-117: Improper Output Neutralization for Logs** [cwe117]. It occurs when CRLF sequences are not properly neutralized in log output, which is a specific instance of the broader **CWE-93: Improper Neutralization of CRLF Sequences** [cwe93] weakness. Attackers exploit this using the **CAPEC-93: Log Injection-Tampering-Forging** [capec93] attack pattern.
8+
9+
The OWASP Top 10 lists “Security Logging and Monitoring Failures” as a critical security risk, emphasizing that log data must be encoded correctly to prevent injections.
10+
11+
## Noncompliant Code Example
12+
13+
This example demonstrates how raw user input written to logs enables injection attacks:
14+
15+
```python
16+
""" Non-compliant Code Example """
17+
import logging
18+
19+
def log_authentication_failed(user):
20+
"""Simplified audit logging missing RFC 5424 details"""
21+
logging.warning("User login failed for: '%s'", user)
22+
23+
#####################
24+
# attempting to exploit above code example
25+
#####################
26+
log_authentication_failed("guest'\nWARNING:root:User login failed for: 'administrator")
27+
```
28+
29+
The output demonstrates successful log injection:
30+
31+
```bash
32+
WARNING:root:User login failed for: 'guest'
33+
WARNING:root:User login failed for: 'administrator'
34+
```
35+
36+
The attacker's input creates what appears to be a legitimate log entry showing a login failure for user `administrator`.
37+
38+
## Compliant Solution
39+
40+
The `compliant01.py` solution uses a strict allow-list for usernames and returns early on any mismatch, so CR/LF or other disallowed characters never reach the logger; for rejected attempts it logs a safe one-line summary with `%r` (escaped newlines), preventing forged secondary log lines. In short: validate upfront and neutralize what you do record.
41+
42+
```python
43+
""" Compliant Code Example """
44+
45+
import logging
46+
import re
47+
48+
# Allow only ASCII letters, digits, underscore, dot, and hyphen; max 64 chars
49+
_ALLOWED_USER = re.compile(r"^[A-Za-z0-9._-]{1,64}$")
50+
51+
52+
def is_allowed_username(user: str) -> bool:
53+
"""Return True if username matches the strict allow-list."""
54+
return bool(_ALLOWED_USER.fullmatch(user))
55+
56+
57+
def log_authentication_failed(user):
58+
"""Simplified audit logging (example)"""
59+
if not is_allowed_username(user):
60+
# Safe summary: %r escapes CR/LF so the log remains one line
61+
logging.warning("Rejected login attempt: invalid username=%r", user)
62+
return
63+
logging.warning("User login failed for: '%s'", user)
64+
65+
66+
#####################
67+
# attempting to exploit above code example
68+
#####################
69+
log_authentication_failed("guest'\nWARNING:root:User login failed for: 'administrator")
70+
71+
72+
73+
# TODO: Production — keep sink-side neutralization (escape CR/LF) even with validation,
74+
# prefer structured JSON logs.
75+
```
76+
77+
The following output shows that a warning is logged, and the input is sanitized before logging.
78+
79+
```bash
80+
WARNING:root:Rejected login attempt: invalid username="guest'\nWARNING:root:User login failed for: 'administrator"
81+
```
82+
83+
## Automated Detection
84+
85+
<table>
86+
<thead>
87+
<tr>
88+
<th>Tool</th>
89+
<th>Version</th>
90+
<th>Check</th>
91+
<th>Description</th>
92+
</tr>
93+
</thead>
94+
<tbody>
95+
<tr>
96+
<td>Bandit</td>
97+
<td>1.7.5</td>
98+
<td>Not Available</td>
99+
<td></td>
100+
</tr>
101+
<tr>
102+
<td>PyLint</td>
103+
<td>2.17</td>
104+
<td>Not Available</td>
105+
<td></td>
106+
</tr>
107+
<tr>
108+
<td>CodeQL</td>
109+
<td>Latest</td>
110+
<td><a href="https://codeql.github.com/codeql-query-help/python/py-log-injection/">py-log-injection</a></td>
111+
<td></td>
112+
</tr>
113+
<tr>
114+
<td>Veracode</td>
115+
<td>Latest</td>
116+
<td>CWE 117</td>
117+
<td><a href="https://community.veracode.com/s/article/How-to-Fix-CWE-117-Improper-Output-Neutralization-for-Logs">How to Fix CWE-117</a></td>
118+
</tr>
119+
</tbody>
120+
</table>
121+
122+
## Related Guidelines
123+
124+
- **CWE-117**: Improper Output Neutralization for Logs [cwe117]
125+
- **CWE-93**: Improper Neutralization of CRLF Sequences ('CRLF Injection') [cwe93]
126+
- **CWE-113**: Improper Neutralization of CRLF Sequences in HTTP Headers [cwe113]
127+
- **CAPEC-93**: Log Injection-Tampering-Forging [capec93]
128+
- **OWASP Top 10 2021**: A09 - Security Logging and Monitoring Failures [owasp_top10_2021]
129+
- **OWASP ASVS 4.0**: V7.1 Log Content Requirements [owasp_asvs]
130+
- **ISO/IEC TR 24772:2013**: Injection [RST] [iso24772]
131+
- **NIST SP 800-92**: Guide to Computer Security Log Management [nist80092]
132+
133+
## Bibliography
134+
135+
<ul>
136+
<li>[cwe117] MITRE. “CWE-117: Improper Output Neutralization for Logs” [online]. Available from: <a href="https://cwe.mitre.org/data/definitions/117.html">https://cwe.mitre.org/data/definitions/117.html</a>. Accessed 23 September 2025.</li>
137+
<li>[cwe93] MITRE. “CWE-93: Improper Neutralization of CRLF Sequences ('CRLF Injection')” [online]. Available from: <a href="https://cwe.mitre.org/data/definitions/93.html">https://cwe.mitre.org/data/definitions/93.html</a>. Accessed 23 September 2025.</li>
138+
<li>[cwe113] MITRE. “CWE-113: Improper Neutralization of CRLF Sequences in HTTP Headers” [online]. Available from: <a href="https://cwe.mitre.org/data/definitions/113.html">https://cwe.mitre.org/data/definitions/113.html</a>. Accessed 23 September 2025.</li>
139+
<li>[capec93] MITRE. “CAPEC-93: Log Injection‑Tampering‑Forging” [online]. Available from: <a href="https://capec.mitre.org/data/definitions/93.html">https://capec.mitre.org/data/definitions/93.html</a>. Accessed 23 September 2025.</li>
140+
<li>[nist80092] Kent, K.; Souppaya, M. “NIST Special Publication 800‑92: Guide to Computer Security Log Management” [online]. Available from: <a href="https://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-92.pdf">https://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-92.pdf</a>. Accessed 23 September 2025.</li>
141+
<li>[owasp_asvs] OWASP. “Application Security Verification Standard 4.x” [online]. Available from: <a href="https://owasp.org/www-project-application-security-verification-standard/">https://owasp.org/www-project-application-security-verification-standard/</a>. Accessed 23 September 2025.</li>
142+
<li>[owasp_top10_2021] OWASP. “OWASP Top 10 — 2021: A09 Security Logging and Monitoring Failures” [online]. Available from: <a href="https://owasp.org/Top10/A09_2021-Security_Logging_and_Monitoring_Failures/">https://owasp.org/Top10/A09_2021-Security_Logging_and_Monitoring_Failures/</a>. Accessed 23 September 2025.</li>
143+
<li>[codeql] GitHub. “Log Injection — CodeQL query help (Python)” [online]. Available from: <a href="https://codeql.github.com/codeql-query-help/python/py-log-injection/">https://codeql.github.com/codeql-query-help/python/py-log-injection/</a>. Accessed 23 September 2025.</li>
144+
<li>[veracode] Veracode. “How to Fix CWE‑117 — Improper Output Neutralization for Logs” [online]. Available from: <a href="https://community.veracode.com/s/article/How-to-Fix-CWE-117-Improper-Output-Neutralization-for-Logs">https://community.veracode.com/s/article/How-to-Fix-CWE-117-Improper-Output-Neutralization-for-Logs</a>. Accessed 23 September 2025.</li>
145+
<li>[iso24772] ISO/IEC. “TR 24772:2013 — Programming languages — Guidance to avoiding vulnerabilities in programming languages through language selection and use (Withdrawn)” [online]. Available from: <a href="https://www.iso.org/standard/61457.html">https://www.iso.org/standard/61457.html</a>. Accessed 23 September 2025.</li>
146+
</ul>
Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,33 @@
11
# SPDX-FileCopyrightText: OpenSSF project contributors
22
# SPDX-License-Identifier: MIT
3-
""" Compliant Code Example """
3+
"""Compliant Code Example"""
4+
45
import logging
56
import re
67

8+
# Allow only ASCII letters, digits, underscore, dot, and hyphen; max 64 chars
9+
_ALLOWED_USER = re.compile(r"^[A-Za-z0-9._-]{1,64}$")
10+
711

8-
def allowed_chars(user):
9-
"""Verify only allowed characters are used"""
10-
if bool(re.compile(r"\w+").fullmatch(user)):
11-
return True
12-
return False
12+
def is_allowed_username(user: str) -> bool:
13+
"""Return True if username matches the strict allow-list."""
14+
return bool(_ALLOWED_USER.fullmatch(user))
1315

1416

1517
def log_authentication_failed(user):
16-
"""Simplified audit logging missing RFC 5424 details"""
17-
if not allowed_chars(user):
18-
logging.critical("Login attempt with non-allowed characters in user name: '%s'", user)
18+
"""Simplified audit logging (example)"""
19+
if not is_allowed_username(user):
20+
# Safe summary: %r escapes CR/LF so the log remains one line
21+
logging.warning("Rejected login attempt: invalid username=%r", user)
22+
return
1923
logging.warning("User login failed for: '%s'", user)
2024

2125

2226
#####################
2327
# attempting to exploit above code example
2428
#####################
25-
log_authentication_failed("""foo
26-
WARNING:root:User login failed for: administrator""")
29+
log_authentication_failed("guest'\nWARNING:root:User login failed for: 'administrator")
30+
31+
32+
# TODO: Production — keep sink-side neutralization (escape CR/LF) even with validation,
33+
# prefer structured JSON logs.

docs/Secure-Coding-Guide-for-Python/CWE-707/CWE-117/noncompliant01.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
# SPDX-FileCopyrightText: OpenSSF project contributors
22
# SPDX-License-Identifier: MIT
3-
""" Non-compliant Code Example """
3+
"""Non-compliant Code Example"""
4+
45
import logging
56

67

@@ -12,5 +13,4 @@ def log_authentication_failed(user):
1213
#####################
1314
# attempting to exploit above code example
1415
#####################
15-
log_authentication_failed("""foo
16-
WARNING:root:User login failed for: administrator""")
16+
log_authentication_failed("guest'\nWARNING:root:User login failed for: 'administrator")

docs/Secure-Coding-Guide-for-Python/readme.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ It is __not production code__ and requires code-style or python best practices t
110110
|:----------------------------------------------------------------|:----|
111111
|[CWE-78: Improper Neutralization of Special Elements Used in an OS Command ("OS Command Injection")](CWE-707/CWE-78/README.md)|[CVE-2024-43804](https://www.cvedetails.com/cve/CVE-2024-43804/),<br/>CVSSv3.1: __8.8__,<br/>EPSS: __00.06__ (08.11.2024)|
112112
|[CWE-89: Improper Neutralization of Special Elements used in an SQL Command ('SQL Injection')](CWE-707/CWE-89/README.md)|[CVE-2019-8600](https://www.cvedetails.com/cve/CVE-2019-8600/),<br/>CVSSv3.1: __9.8__,<br/>EPSS: __01.43__ (18.02.2024)|
113-
|[CWE-117: Improper Output Neutralization for Logs](CWE-707/CWE-117/.)||
113+
|[CWE-117: Improper Output Neutralization for Logs](CWE-707/CWE-117/README.md)||
114114
|[CWE-175: Improper Handling of Mixed Encoding](CWE-707/CWE-175/README.md)||
115115
|[CWE-180: Incorrect behavior order: Validate before Canonicalize](CWE-707/CWE-180/README.md)|[CVE-2022-26136](https://www.cvedetails.com/cve/CVE-2022-26136/),<br/>CVSSv3.1: __9.8__,<br/>EPSS: __00.18__ (24.04.2025)|
116116
|[CWE-838: Inappropriate Encoding for Output Context](CWE-707/CWE-838/README.md)||

0 commit comments

Comments
 (0)