T09 · Insecure Skill Coding Practices
- Location
scripts/tensorslab_image.py:76- Finding
Unvalidated API-Provided URLs Permit Arbitrary Network Requests and Unbounded Downloads
- Content
View full analysis
Path: """Download an image from URL to local path.""" try: response = _SESSION.get(url, timeout=30) response.raise_for_status() content_type = response.headers.get('content-type', '').split(';')[0].strip() ext = mimetypes.guess_extension(content_type) if ext == '.jpe': ext = '.jpg' if not ext: ext = Path(urlparse(url).path).suffix if not ext or len(ext) > 6: ext = '.png' final_path = output_path.with_suffix(ext) with open(final_path, 'wb') as f: f.write(response.content) return final_path except Exception as e: logger.warning(f"Warning: Failed to download image from {url}: {e}") return None ``` The URL is obtained from API-controlled task data and passed directly to the download function: ```python for i, url in enumerate(urls): filename = f"{task_id}_{i}" output_path = output_dir / filename logger.info(f"📥 Downloading image {i+1}/{len(urls)}") final_path = download_image(url, output_path) if final_path: downloaded_files.append(str(final_path)) ``` ### Technical Analysis The application trusts image URLs returned by the remote task-status API. It does not validate: - The URL scheme. - The destination hostname or resolved IP address. - Whether the destination belongs to an approved image-storage domain. - Redirect destinations. - Whether the resolved address is loopback, private, link-local, or otherwise internal. - The response body size. - Whether the response is actually a valid image. The `Content-Type` header is used only to determine the output extension. I ...[truncated 1637 chars]- Remediation
View remediation
MAX_IMAGE_BYTES: raise TensorsLabAPIError("Downloaded image exceeds size limit") output.write(chunk) ``` ]]>
