T09 · Insecure Skill Coding Practices
Warning
- Location
- scripts/upload_pdf.py:65
- Finding
- Unbounded Whole-File Buffering Can Exhaust Memory## Vulnerability Details **File Location**: `scripts/upload_pdf.py:65-66` and `scripts/upload_pdf.py:94-125` **Vulnerability Type**: Unbounded memory allocation from a caller-selected file **Risk Level**: Medium ### Vulnerable 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 `bytes` objects. 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 1. An attacker or untrusted workflow supplies a path to a very large accessible file, including a large sparse file. 2. The Agent invokes `scripts/upload_pdf.py` with that path. 3. `f.re ...[truncated 712 chars]
- 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.
