T09 · Insecure Skill Coding Practices
- Location
scripts/encoding_detector.py:38- Finding
Unbounded Full-File Read Can Cause Memory Exhaustion
- Content
View full analysis
Vulnerability Details
File Location:
scripts/encoding_detector.py, lines 38–39
Vulnerability Type: Unbounded memory allocation / denial of service
Risk Level: MediumVulnerable Code:
python with open(args.file, "rb") as f: size = len(f.read())Technical Analysis
The program loads the entire selected file into memory solely to calculate its byte size. This operation has no upper bound. Although
detect_encoding()limits its initial sample to 10,000 bytes, the subsequentf.read()negates that protection.If an attacker can influence the
--fileargument or provide a file that the application processes, they can select a very large readable file. Memory consumption will then scale with the full input size. A special stream-backed path may introduce additional availability risks if reading does not terminate as expected.Attack Path
- An attacker creates, uploads, or identifies a very large file readable by the process.
- The attacker causes the skill to run with that path through
--file. - Encoding detection reads a bounded 10,000-byte sample.
- The size calculation calls
f.read()without a limit and attempts to hold the entire file in memory. - The process consumes excessive memory and may be terminated by the operating system, disrupting the agent or hosting service.
Impact Assessment
Successful exploitation can cause denial of service through excessive memory consumption, process termination, degraded host performance, or disruption of concurrent workloads. The flaw does not itself grant additional privileges, execute attacker-controlled code, disclose file contents in output, or cross an access-control boundary. Its scope is limited to files the current process can already open.
- Remediation
View remediation
Remediation Suggestions
Obtain the file size from filesystem metadata instead of reading the content:
python import os size = os.path.getsize(args.file)For additional hardening:
- Use
os.stat()andstat.S_ISREG()to reject devices, FIFOs, sockets, and other non-regular files when they are outside the intended use case. - Apply an explicit maximum accepted file size before processing.
- Catch
OSErrorand return a controlled error rather than a traceback. - If consistency between detection and reported size matters, open the file once, validate it with
os.fstat(f.fileno()), and read only the bounded detection sample. - Run the skill with memory and execution-time limits as defense in depth.
- Use
