T05 · Unauthorized Access and Privilege Escalation
Error
- Location
- scripts/gen.py:115
- Finding
- Undocumented Arbitrary Local File Upload to a Configurable Remote Endpoint## Vulnerability Details **File Location**: `scripts/gen.py:115-141, 203-224` **Vulnerability Type**: Arbitrary local file disclosure through undocumented image-editing functionality **Risk Level**: High ### Vulnerable Code ```python # Image file img_data = image_path.read_bytes() img_mime = "image/jpeg" if image_path.suffix.lower() in (".jpg", ".jpeg") else "image/png" parts.append( ( f"--{boundary}\r\n" f'Content-Disposition: form-data; name="image"; filename="{image_path.name}"\r\n' f"Content-Type: {img_mime}\r\n\r\n" ).encode("utf-8") + img_data + b"\r\n" ) parts.append(f"--{boundary}--\r\n".encode("utf-8")) body = b"".join(parts) req = urllib.request.Request( url, method="POST", headers={ "Authorization": f"Bearer {api_key}", "Content-Type": f"multipart/form-data; boundary={boundary}", }, data=body, ) ``` ```python if args.input: # Edit mode input_path = args.input.strip() if input_path.startswith("http"): print(f"Downloading input image...", file=sys.stderr) local_input = download_to_temp(input_path) else: local_input = Path(input_path) print(f"Editing image with model={args.model} format={response_format}...", file=sys.stderr) response = request_edit( base_url=base_url, api_key=api_key, prompt=args.prompt, model=args.model, image_path=local_input, response_format=response_format, size=args.size, aspect_ratio=args.aspect_ratio, count=args.count, ) ``` ### Technical Analysis The `--input` argument accepts an arbitrary local path. The selected file is read in full with `Path.read_bytes()` and included in a multipart request to `${VAPI_BASE_URL}/images/edits`. The implementation does not: - Restrict files to an approved media directory. - Verify that the selected file is an image by inspe ...[truncated 1942 chars]
- Remediation
- ## Remediation Suggestions 1. Remove edit mode if it is not part of the intended and documented Skill functionality. 2. If editing is required, document clearly that the selected image and prompt are transmitted to the configured API provider. 3. Require explicit user approval immediately before uploading a local file. 4. Resolve the path with `Path.resolve()` and constrain it to one or more user-approved media directories. 5. Reject symlinks or validate their fully resolved targets to prevent directory-boundary bypass. 6. Validate image content using a trusted image decoder rather than relying on the filename extension. 7. Allow only explicitly supported image formats and enforce conservative file-size and pixel-count limits. 8. Reject sensitive locations, device files, sockets, and other non-regular files. 9. Display the resolved destination host and local source path before transmission. 10. Keep edit functionality separate from generation functionality so generation does not require broad local-file access.
