Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,86 @@ except ZeroDivisionError:

In `compliant01.py`, using `logging` and loglevels allows better integration with a centralized logging system.

## Non-Compliant Code Example (Audit Logging)

Log security-critical events such as authentication failures to allow detection of brute-force attacks and unauthorized access attempts.

In `noncompliant02.py`, the `login()` function silently returns `False` on authentication failure and does not log the event.Due to this an attacker can perform repeated login attempts without any trace in the system, making incident detection and forensic analysis impossible, and making brute-force attacks a possibility.

*[noncompliant02.py](noncompliant02.py):*

```python
"""Non-compliant Code Example"""


def login(username: str, password: str) -> bool:
"""Authenticate user without any audit logging"""
# TODO: use a proper credential store
if username == "admin" and password == "s3cr3t":
return True
return False


#####################
# Trying to exploit above code example
#####################
login("admin", "wrong_password")
login("admin", "password123!")
login("admin", "sEcrEt")
```

Running `noncompliant02.py` produces no output. Three failed login attempts are completely invisible to operators and security monitoring systems.

## Compliant Solution (Audit Logging)

The `compliant02.py` solution configures a `logging.Formatter` with timestamp, severity, and a structured event message. Both successful and failed authentication attempts are logged with the event type and username, without exposing sensitive data such as the password. Successful logins are logged at `INFO` level and failures at `WARNING` level.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In case you do adapt the code then we will have to explain why we use json instead of strictly following the rfc. Here a draft for that explanation:

RFC 5424 defines the standard transport for system logs without JSON. This guide recommends using structured JSON payloads to ensure logs are machine-readable for automated security analysis instead plain-text as defined in RFC 5424 as supported by:


Logging successful logins is essential because a success following repeated failures indicates a compromised account, and success logs establish a baseline of normal activity needed to detect anomalies.

*[compliant02.py](compliant02.py):*

```python
"""Compliant Code Example"""

import logging

logging.basicConfig(
format="%(asctime)s %(levelname)s event=%(message)s",
datefmt="%Y-%m-%dT%H:%M:%S",
level=logging.INFO,
)
_audit = logging.getLogger("audit")


def login(username: str, password: str) -> bool:
"""Authenticate user with audit logging"""
# TODO: use a proper credential store
if username == "admin" and password == "s3cr3t":
_audit.info("login_success user=%s", username)
return True
_audit.warning("login_failed user=%s", username)
# TODO: forward logs to a remote logging service in production
return False


#####################
# Trying to exploit above code example
#####################
login("admin", "wrong_password")
login("admin", "password123!")
login("admin", "s3cr3t")
```

**Output of `compliant02.py`:**

```bash
2026-03-31T11:50:30 WARNING event=login_failed user=admin
2026-03-31T11:50:30 WARNING event=login_failed user=admin
2026-03-31T11:50:30 INFO event=login_success user=admin
```

Each attempt is now visible, enabling operators to detect brute-force patterns, identify compromised accounts, and trigger automated responses.

## Automated Detection

|Tool|Version|Checker|Description|
Expand All @@ -67,5 +147,6 @@ In `compliant01.py`, using `logging` and loglevels allows better integration wit
|||
|:---|:---|
|MITRE CWE Pillar|[CWE-693: Protection Mechanism Failure (4.16) (mitre.org)](https://cwe.mitre.org/data/definitions/693.html)|
|MITRE CWE Base|[CWE-778: Numeric Truncation Error](https://cwe.mitre.org/data/definitions/778.html)|
|MITRE CWE Base|[CWE-778: Insufficient Logging](https://cwe.mitre.org/data/definitions/778.html)|
|[SEI CERT](https://wiki.sei.cmu.edu/confluence/display/java/SEI+CERT+Oracle+Coding+Standard+for+Java)|[ERR02-J. Prevent exceptions while logging data](https://wiki.sei.cmu.edu/confluence/display/java/ERR02-J.+Prevent+exceptions+while+logging+data)|
|[OWASP Top 10](https://owasp.org/Top10/)|[A09:2021 – Security Logging and Monitoring Failures](https://owasp.org/Top10/A09_2021-Security_Logging_and_Monitoring_Failures/)|
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# SPDX-FileCopyrightText: OpenSSF project contributors
# SPDX-License-Identifier: MIT
"""Compliant Code Example"""

import logging

logging.basicConfig(
format="%(asctime)s %(levelname)s event=%(message)s",
datefmt="%Y-%m-%dT%H:%M:%S",
level=logging.INFO,
)
_audit = logging.getLogger("audit")


def login(username: str, password: str) -> bool:
"""Authenticate user with audit logging"""
# TODO: use a proper credential store
if username == "admin" and password == "s3cr3t":
_audit.info("login_success user=%s", username)
return True
_audit.warning("login_failed user=%s", username)
# TODO: forward logs to a remote logging service in production
return False
Comment on lines +5 to +23
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here a code example that is a little closer to the rfc with timestamps and such but still missing some stuff added as TODO.

Suggested change
import logging
logging.basicConfig(
format="%(asctime)s %(levelname)s event=%(message)s",
datefmt="%Y-%m-%dT%H:%M:%S",
level=logging.INFO,
)
_audit = logging.getLogger("audit")
def login(username: str, password: str) -> bool:
"""Authenticate user with audit logging"""
# TODO: use a proper credential store
if username == "admin" and password == "s3cr3t":
_audit.info("login_success user=%s", username)
return True
_audit.warning("login_failed user=%s", username)
# TODO: forward logs to a remote logging service in production
return False
# SPDX-FileCopyrightText: OpenSSF project contributors
# SPDX-License-Identifier: MIT
"""Compliant Code Example"""
import json
import logging
from datetime import datetime, timezone
logging.basicConfig(format="%(message)s", level=logging.INFO)
def audit_log(event: str, user: str, outcome: str) -> None:
"""Write a simple audit log entry in JSON format"""
# TODO: add hostname, app_name, proc_id per RFC 5424
# TODO: forward logs to a remote logging service
# TODO: sanitize user input to prevent log injection, see pyscg-0022
entry = {
"timestamp": datetime.now(timezone.utc).isoformat(timespec="milliseconds"),
"event": event,
"user": user,
"outcome": outcome,
}
logging.info("%s", json.dumps(entry))
def login(username: str, password: str) -> bool:
"""Authenticate user with audit logging"""
# TODO: use a proper credential store, see pyscg-0041
if username == "admin" and password == "s3cr3t":
audit_log("login", username, "success")
return True
audit_log("login", username, "failure")
return False
#####################
# Trying to exploit above code example
#####################
login("admin", "wrong_password")
login("admin", "password123!")
login("admin", "s3cr3t")



#####################
# Trying to exploit above code example
#####################
login("admin", "wrong_password")
login("admin", "password123!")
login("admin", "s3cr3t")
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# SPDX-FileCopyrightText: OpenSSF project contributors
# SPDX-License-Identifier: MIT
"""Non-compliant Code Example"""


def login(username: str, password: str) -> bool:
"""Authenticate user without any audit logging"""
# TODO: use a proper credential store
if username == "admin" and password == "s3cr3t":
return True
return False


#####################
# Trying to exploit above code example
#####################
login("admin", "wrong_password")
login("admin", "password123!")
login("admin", "sEcrEt")
Loading