T09 · Insecure Skill Coding Practices
Warning
- Location
- blind_judge_manager.py:162
- Finding
- Unbounded Input Handling in Deprecated Compatibility CLI## Vulnerability Details **File Location**: `blind_judge_manager.py`, lines 162–178 **Vulnerability Type**: Unbounded memory consumption from attacker-controlled file or standard input **Risk Level**: Medium ### Vulnerable Code ```python def _read_payload_text() -> str: """Read payload from `--file PATH` if given, else stdin (parity with judge_pipeline.py).""" import os import sys argv = sys.argv[1:] if "--file" in argv: idx = argv.index("--file") if idx + 1 >= len(argv): raise ValueError("--file requires a path argument") path = argv[idx + 1] if not os.path.isfile(path): raise ValueError(f"--file path is not a regular file: {path}") with open(path, "r", encoding="utf-8") as f: return f.read() return sys.stdin.read() ``` ### Technical Analysis The deprecated compatibility CLI reads the entire payload into memory through either `f.read()` or `sys.stdin.read()` without enforcing a maximum size. The resulting string is subsequently passed to `json.loads()`, which can require substantial additional memory to construct the parsed object. This differs from the canonical `judge_pipeline.py`, which limits file and standard-input payloads to 64 MB. Although the affected script is deprecated, it remains included in the package, is documented as a compatibility entry point, and is directly executable. Legacy integrations may therefore continue to expose the vulnerable path. An attacker does not gain code execution or additional system privileges through this flaw. Exploitation requires the ability to cause the compatibility CLI to process a large file or input stream. ### Attack Path 1. An attacker supplies or causes legacy tooling to generate an extremely large JSON payload. 2. The integration invokes `blind_judge_manager.py` with the payload through `--file` or standard input. 3. `_read_payload_text()` reads ...[truncated 759 chars]
- Remediation
- ## Remediation Suggestions Apply the same bounded-input controls used by `judge_pipeline.py`: 1. Define a shared maximum, such as: ```python MAX_PAYLOAD_BYTES = 64 * 1024 * 1024 ``` 2. Before reading a file, reject it when `os.path.getsize(path)` exceeds the limit. 3. Read standard input with `sys.stdin.read(MAX_PAYLOAD_BYTES + 1)` and reject the payload if the returned content exceeds the limit. 4. Return a clean JSON error and a nonzero exit status for oversized payloads. 5. Add regression tests covering oversized file and standard-input payloads. 6. Prefer removing the deprecated executable in the next major release or replacing it with a thin wrapper around the bounded canonical implementation to prevent future security divergence. Example hardened implementation: ```python MAX_PAYLOAD_BYTES = 64 * 1024 * 1024 def _read_payload_text() -> str: import os import sys argv = sys.argv[1:] if "--file" in argv: idx = argv.index("--file") if idx + 1 >= len(argv): raise ValueError("--file requires a path argument") path = argv[idx + 1] if not os.path.isfile(path): raise ValueError(f"--file path is not a regular file: {path}") if os.path.getsize(path) > MAX_PAYLOAD_BYTES: raise ValueError( f"payload exceeds size limit ({MAX_PAYLOAD_BYTES} bytes)" ) with open(path, "r", encoding="utf-8") as f: return f.read() text = sys.stdin.read(MAX_PAYLOAD_BYTES + 1) if len(text) > MAX_PAYLOAD_BYTES: raise ValueError( f"payload exceeds size limit ({MAX_PAYLOAD_BYTES} bytes)" ) return text ```
