T09 · Insecure Skill Coding Practices
- Location
blind_judge_manager.py:162- Finding
Unbounded Input Handling in Deprecated Compatibility CLI
- Content
View full analysis
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: MediumVulnerable 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()orsys.stdin.read()without enforcing a maximum size. The resulting string is subsequently passed tojson.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
- An attacker supplies or causes legacy tooling to generate an extremely large JSON payload.
- The integration invokes
blind_judge_manager.pywith the payload through--fileor standard input. _read_payload_text()reads ...[truncated 759 chars]
- Remediation
View remediation
Remediation Suggestions
Apply the same bounded-input controls used by
judge_pipeline.py:- Define a shared maximum, such as:
python MAX_PAYLOAD_BYTES = 64 * 1024 * 1024 - Before reading a file, reject it when
os.path.getsize(path)exceeds the limit. - Read standard input with
sys.stdin.read(MAX_PAYLOAD_BYTES + 1)and reject the payload if the returned content exceeds the limit. - Return a clean JSON error and a nonzero exit status for oversized payloads.
- Add regression tests covering oversized file and standard-input payloads.
- 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- Define a shared maximum, such as:
