T09 · Insecure Skill Coding Practices
- Location
scripts/upload_pdf.py:65- Finding
Unbounded Whole-File Buffering Can Exhaust Memory
- Content
View full analysis
Vulnerability Details
File Location:
scripts/upload_pdf.py:65-66andscripts/upload_pdf.py:94-125
Vulnerability Type: Unbounded memory allocation from a caller-selected file
Risk Level: MediumVulnerable Code
python # Read file content with open(file_path, "rb") as f: file_data = f.read()python # Build multipart body body = b"" # upload_id field body += f"--{boundary}\r\n".encode() body += b'Content-Disposition: form-data; name="upload_id"\r\n\r\n' body += upload_id.encode() + b'\r\n' # seq field (0 for single-part upload) body += f"--{boundary}\r\n".encode() body += b'Content-Disposition: form-data; name="seq"\r\n\r\n' body += b'0\r\n' # size field body += f"--{boundary}\r\n".encode() body += b'Content-Disposition: form-data; name="size"\r\n\r\n' body += str(file_size).encode() + b'\r\n' # file field body += f"--{boundary}\r\n".encode() body += f'Content-Disposition: form-data; name="file"; filename="{file_name}"\r\n'.encode() body += b'Content-Type: application/octet-stream\r\n\r\n' body += file_data body += b'\r\n' # End boundary body += f"--{boundary}--\r\n".encode()Technical Analysis
The script reads the entire caller-selected file into memory without enforcing a maximum size. It then constructs a second complete multipart request body using repeated concatenation of immutable
bytesobjects. These operations can temporarily require multiple file-sized allocations.This implementation does not provide the bounded-memory multipart behavior advertised by the Skill. Although the Feishu API flow uses an upload-part endpoint, the script submits the file as one in-memory part rather than streaming or uploading bounded chunks.
Attack Path
- An attacker or untrusted workflow supplies a path to a very large accessible file, including a large sparse file.
- The Agent invokes
scripts/upload_pdf.pywith that path. - `f.re ...[truncated 712 chars]
- Remediation
View remediation
Remediation Suggestions
- Enforce an explicit maximum accepted file size before reading or uploading the file.
- Implement Feishu multipart uploading with fixed-size chunks and the correct
block_num. - Read one bounded chunk at a time instead of calling
f.read()without a size. - Use a streaming multipart implementation where supported rather than assembling the complete request body manually.
- Avoid repeated immutable byte-string concatenation.
- Apply process-level memory limits as defense in depth.
- Reject files whose size exceeds either the configured policy or Feishu API limits before obtaining an upload ID.
