T09 · Insecure Skill Coding Practices
Error
- Location
- scripts/generate_image.py:83
- Finding
- Arbitrary Local File Disclosure Through Reference Image Input## Vulnerability Details **File Location**: `scripts/generate_image.py`, lines 83-109 **Vulnerability Type**: Unrestricted local file read and external transmission **Risk Level**: High ### Vulnerable Code ```python def resolve_reference_image(value: str) -> Any: if value.startswith("http://") or value.startswith("https://"): return value path = Path(value) if path.exists(): return path.read_bytes() return value def call_generate(req: dict[str, Any]) -> dict[str, Any]: prompt = req.get("prompt") if not prompt: raise ValueError("prompt is required") messages = [{"role": "user", "content": [{"text": prompt}]}] reference_image = req.get("reference_image") if reference_image: messages[0]["content"].insert( 0, {"image": resolve_reference_image(reference_image)} ) response = ImageGeneration.call( model=MODEL_NAME, messages=messages, size=req.get("size", DEFAULT_SIZE), api_key=os.getenv("DASHSCOPE_API_KEY"), negative_prompt=req.get("negative_prompt"), style=req.get("style"), seed=req.get("seed"), ) ``` ### Technical Analysis The caller-controlled `reference_image` field is interpreted as a local filesystem path whenever that path exists. The script reads the entire file without verifying that it is an image, restricting it to an approved directory, checking symlink traversal, imposing a size limit, or requesting confirmation. The resulting bytes are inserted into `messages` and passed to the external DashScope SDK. Consequently, any local file readable by the process can be treated as a reference image and transmitted to the provider. Supporting reference images is necessary for the declared functionality, but unrestricted access to the entire readable filesystem exceeds the minimum privilege required. ### Attack Path 1. An attacker obt ...[truncated 1024 chars]
- Remediation
- ## Remediation Suggestions - Permit local reference images only from a dedicated, explicitly approved input directory. - Resolve the requested path with `Path.resolve()` and verify that it remains beneath the approved directory using `Path.is_relative_to()` or an equivalent safe containment check. - Reject symbolic links or validate the fully resolved target to prevent symlink-based directory escape. - Validate image content using an image decoder rather than trusting the filename extension. - Allowlist supported image formats and enforce strict file-size and pixel-dimension limits. - Reject special files, directories, devices, sockets, and other non-regular files. - Require explicit user confirmation before uploading a local file to an external service. - Consider accepting only HTTPS reference URLs or previously uploaded file identifiers instead of arbitrary local paths.
