Skip to content
Merged
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
11 changes: 6 additions & 5 deletions docs/VULNERABILITY_CATALOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,12 @@ from each file's header comment, so this page cannot drift from the source.

## Totals

- **Test cases:** 113
- **Expected detections:** 113
- **`VULNERABLE:` markers:** 207 (individual lines a scanner should flag)
- **`SAFE:` markers:** 125 (lines a scanner must not flag — the false-positive control group)
- **Test cases:** 114
- **Expected detections:** 114
- **`VULNERABLE:` markers:** 210 (individual lines a scanner should flag)
- **`SAFE:` markers:** 127 (lines a scanner must not flag — the false-positive control group)
- **Languages:** 8 — dotenv, go, java, javascript, json, python, ruby, text
- **CWE categories:** 83 — CWE-20, CWE-22, CWE-78, CWE-79, CWE-89, CWE-90, CWE-94, CWE-95, CWE-113, CWE-117, CWE-129, CWE-190, CWE-201, CWE-203, CWE-208, CWE-209, CWE-256, CWE-287, CWE-288, CWE-291, CWE-295, CWE-306, CWE-307, CWE-319, CWE-321, CWE-326, CWE-327, CWE-329, CWE-330, CWE-338, CWE-345, CWE-346, CWE-347, CWE-352, CWE-362, CWE-377, CWE-384, CWE-400, CWE-434, CWE-441, CWE-460, CWE-472, CWE-475, CWE-480, CWE-488, CWE-489, CWE-502, CWE-506, CWE-509, CWE-512, CWE-521, CWE-525, CWE-532, CWE-598, CWE-601, CWE-602, CWE-611, CWE-613, CWE-614, CWE-620, CWE-639, CWE-640, CWE-643, CWE-681, CWE-693, CWE-759, CWE-776, CWE-798, CWE-835, CWE-862, CWE-863, CWE-915, CWE-916, CWE-918, CWE-922, CWE-942, CWE-943, CWE-1021, CWE-1236, CWE-1321, CWE-1333, CWE-1336, CWE-1357
- **CWE categories:** 84 — CWE-20, CWE-22, CWE-78, CWE-79, CWE-89, CWE-90, CWE-94, CWE-95, CWE-113, CWE-117, CWE-129, CWE-190, CWE-201, CWE-203, CWE-208, CWE-209, CWE-256, CWE-287, CWE-288, CWE-291, CWE-295, CWE-306, CWE-307, CWE-319, CWE-321, CWE-326, CWE-327, CWE-329, CWE-330, CWE-338, CWE-345, CWE-346, CWE-347, CWE-352, CWE-362, CWE-377, CWE-384, CWE-400, CWE-434, CWE-441, CWE-460, CWE-472, CWE-475, CWE-480, CWE-488, CWE-489, CWE-502, CWE-506, CWE-509, CWE-512, CWE-521, CWE-525, CWE-532, CWE-598, CWE-601, CWE-602, CWE-611, CWE-613, CWE-614, CWE-620, CWE-639, CWE-640, CWE-643, CWE-681, CWE-693, CWE-732, CWE-759, CWE-776, CWE-798, CWE-835, CWE-862, CWE-863, CWE-915, CWE-916, CWE-918, CWE-922, CWE-942, CWE-943, CWE-1021, CWE-1236, CWE-1321, CWE-1333, CWE-1336, CWE-1357

## How coverage is scored

Expand Down Expand Up @@ -112,6 +112,7 @@ counts as a detection. See `docs/SCANNER_INTEGRATION.md`.
| Hardcoded secret used to configure session signing | [`hardcoded-session-secret.py`](../vulns/python/hardcoded-session-secret.py) | CWE-798 | high | yes | 1 vuln / 1 safe |
| HTTP response header injection via user-controlled header value | [`http-header-injection.py`](../vulns/python/http-header-injection.py) | CWE-113 | high | yes | 3 vuln / 1 safe |
| Inadequate encryption strength at the credential boundary | [`inadequate-encryption-strength.py`](../vulns/python/inadequate-encryption-strength.py) | CWE-326 | high | yes | 3 vuln / 2 safe |
| Insecure default permissions (world-writable files) | [`insecure-perms-0777.py`](../vulns/python/insecure-perms-0777.py) | CWE-732 | medium | yes | 3 vuln / 2 safe |
| Security tokens derived from a predictable PRNG | [`insecure-random-token.py`](../vulns/python/insecure-random-token.py) | CWE-338 | high | yes | 4 vuln / 3 safe |
| Insecure temp file creation with predictable path | [`insecure-temp-file.py`](../vulns/python/insecure-temp-file.py) | CWE-377 | medium | yes | 3 vuln / 1 safe |
| LDAP injection via unescaped search filter | [`ldap-injection.py`](../vulns/python/ldap-injection.py) | CWE-90 | high | yes | 1 vuln / 1 safe |
Expand Down
35 changes: 31 additions & 4 deletions vulns/VULNERABILITY_CATALOG.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@
"schema": "threatcrush-testbed-catalog/1",
"note": "Generated by scripts/generate-catalog.py \u2014 do not edit by hand.",
"totals": {
"test_cases": 113,
"expected_detections": 113,
"vulnerable_markers": 207,
"safe_markers": 125,
"test_cases": 114,
"expected_detections": 114,
"vulnerable_markers": 210,
"safe_markers": 127,
"languages": [
"dotenv",
"go",
Expand Down Expand Up @@ -91,6 +91,7 @@
"CWE-643",
"CWE-681",
"CWE-693",
"CWE-732",
"CWE-759",
"CWE-776",
"CWE-798",
Expand Down Expand Up @@ -1810,6 +1811,32 @@
78
]
},
{
"id": "py-insecure-perms-0777",
"file": "vulns/python/insecure-perms-0777.py",
"title": "Insecure default permissions (world-writable files)",
"category": "python",
"language": "python",
"cwe": "CWE-732",
"cwes": [
"CWE-732"
],
"severity": "medium",
"expected_detection": true,
"description": "A file or directory is created with mode 0o777 (world-readable,",
"detection_target": "os.chmod(path, 0o777), open(..., mode=0o777), os.mkdir(path, 0o777),",
"safe_guard": "All operations wrapped in `if False:` (unreachable dead code).",
"attribution": "line",
"vulnerable_lines": [
26,
34,
41
],
"safe_lines": [
52,
64
]
},
{
"id": "py-insecure-random-token",
"file": "vulns/python/insecure-random-token.py",
Expand Down
66 changes: 66 additions & 0 deletions vulns/python/insecure-perms-0777.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
"""
@id py-insecure-perms-0777
@test-case Insecure default permissions (world-writable files)
@cwe CWE-732
@severity medium
@language python
@expected-detection true
@description A file or directory is created with mode 0o777 (world-readable,
writable, executable). Any local user can overwrite, execute, or
replace the artifact, leading to privilege escalation or data
tampering. The safe counterpart uses a restrictive default (0o600
for files, 0o700 for dirs) and applies least-privilege explicitly.
@safe-guard All operations wrapped in `if False:` (unreachable dead code).
No filesystem write occurs; the mode literals are only analyzed
statically.
@detection-target os.chmod(path, 0o777), open(..., mode=0o777), os.mkdir(path, 0o777),
pathlib.Path(...).chmod(0o777) — any literal 0o777/511 at a
permission-setting call site.

NEVER RUN IN PRODUCTION - intentional test case for scanner validation.
"""


def write_world_writable_file(path: str, data: bytes) -> None:
if False:
# VULNERABLE: CWE-732 - world-writable file
with open(path, "wb", opener=lambda p, f: os.open(p, f, 0o777)) as fh:
fh.write(data)
return None


def chmod_world_writable(path: str) -> None:
if False:
# VULNERABLE: CWE-732 - chmod 777
os.chmod(path, 0o777)
return None


def mkdir_world_writable(path: str) -> None:
if False:
# VULNERABLE: CWE-732 - directory 777
os.mkdir(path, 0o777)
return None


def write_restricted_file(path: str, data: bytes) -> None:
"""Safe counterpart - the scanner should NOT flag this.

@expected-detection false
"""
if False:
# SAFE: 0o600 - owner read/write only
with open(path, "wb", opener=lambda p, f: os.open(p, f, 0o600)) as fh:
fh.write(data)
return None


def chmod_restricted(path: str) -> None:
"""Safe counterpart - the scanner should NOT flag this.

@expected-detection false
"""
if False:
# SAFE: 0o600
os.chmod(path, 0o600)
return None
Loading