Back to skill

Security audit

smart-image-loader

Security checks for vulnerabilities and agentic risk

Overview

The skill has a coherent image-loading purpose, but its URL downloading, unrestricted local path handling, and shell-based cleanup create material review risks.

Review before installing. Use only with trusted image URLs and known workspace image paths, and avoid following the documented `rm <file_path>` cleanup pattern. The publisher should constrain downloads, validate images and file sizes, confine local paths to the workspace, and perform cleanup through a safe non-shell API.

Vulnerability Patterns
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Agent Memory PoisoningWrites attacker-controlled rules into memory that affect later sessions
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
Findings (3)

T05 · Unauthorized Access and Privilege Escalation

Warning
Location
scripts/smart_image_loader.py:102
Finding

Arbitrary Local File Access Outside the Workspace Boundary

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/smart_image_loader.py:46
Finding

Unrestricted URL Fetching Enables SSRF and Resource Exhaustion

Content
View full analysis
bool: """Check if the input is a URL.""" return input_str.startswith('http://') or input_str.startswith('https://') ``` ```python try: urllib.request.urlretrieve(url, filepath) except Exception: # Fallback to URLLib request with headers req = urllib.request.Request(url, headers={'User-Agent': 'Mozilla/5.0'}) with urllib.request.urlopen(req) as response: with open(filepath, 'wb') as out_file: out_file.write(response.read()) ``` The unrestricted request is initiated from the URL branch: ```python if is_url(input_str): # Download URL to temporary location temp_dir = tempfile.mkdtemp() try: file_path = download_image(input_str, temp_dir) ``` ### Technical Analysis Any string beginning with `http://` or `https://` is accepted as a remote image location. Requests are then made from the Agent's network context without destination validation. The implementation does not provide: - An allowlist of trusted hosts. - Rejection of loopback, private, link-local, multicast, or reserved IP addresses. - DNS rebinding defenses. - Validation of redirect destinations. - Explicit connection or read timeouts. - A maximum response size. - Streaming with a bounded byte count. - Content-Type validation. - Image signature or decoder-based validation. The fallback path calls `response.read()` without a size argument, loading the entire response into memory before writing it. The primary `urlretrieve()` path is also unbounded and can consume disk space. Appending an image extension when one is absent does not establish that the response is an image. Internal service responses, metadata documents, HTML, or arbitrary binary data can therefore ...[truncated 1591 chars]
Remediation
View remediation
MAX_IMAGE_SIZE: raise ValueError("Image exceeds the size limit") out_file.write(chunk) ``` Destination and redirect validation must be implemented in addition to the size limit. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
SKILL.md:96
Finding

Shell Command Injection Risk in Documented Temporary-File Cleanup

Content
View full analysis
` for cleanup ``` The path inserted into that command contains a filename derived from the untrusted URL: ```python filename = url.split('/')[-1] if not filename: filename = 'downloaded_image' # Add extension if missing if not any(filename.lower().endswith(ext) for ext in ['.jpg', '.jpeg', '.png', '.gif', '.webp', '.bmp']): filename += '.jpg' filepath = os.path.join(temp_dir, filename) ``` The path is then returned to the caller: ```python return { 'success': True, 'type': 'url', 'file_path': file_path, 'message': f'Downloaded image from URL: {input_str}', 'cleanup_needed': True } ``` ### Technical Analysis The final URL component is used as a local filename without replacing shell metacharacters with a generated safe name. The Skill subsequently tells the Agent to interpolate the returned path into `rm ` through an `exec` tool. If the Agent constructs a shell command by textual substitution, metacharacters in the URL-derived filename can be interpreted as shell syntax rather than as literal filename characters. Merely surrounding the path with inadequate quoting would not be sufficient in every construction, and the documented instruction does not require any quoting at all. The temporary directory itself is safely generated, but that does not neutralize command syntax embedded in the basename. The dangerous operation occurs when an attacker-influenced path c ...[truncated 1479 chars]
Remediation
View remediation
` through a shell. 2. Keep temporary-file lifecycle management inside the Python script or a trusted non-shell API. 3. Generate a random local basename rather than preserving the final URL component. 4. Use `tempfile.NamedTemporaryFile`, `mkstemp`, or a fixed safe filename inside the private temporary directory. 5. Delete the complete temporary directory with `shutil.rmtree()` after processing. 6. Place cleanup in a `finally` block so it runs for success and failure paths. 7. If an external process must perform deletion, invoke it with an argument array and with shell processing disabled. 8. Never form cleanup commands through string concatenation or interpolation. The existing cleanup attempt also requires correction: ```python cleanup_file(os.path.join(temp_dir, '*')) ``` `os.remove()` does not expand the wildcard and cannot remove the temporary directory. A safer cleanup operation is: ```python import shutil try: # Download and process the image. ... finally: shutil.rmtree(temp_dir, ignore_errors=True) ``` The caller should process the image within the managed temporary-directory lifetime rather than receiving a path that must later be inserted into a shell command. ]]>
Vulnerability Patterns
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
Findings (4)

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding

The documented behavior claims the skill displays images using the read tool, but the described implementation primarily resolves paths or downloads files and leaves display and cleanup to follow-on actions. This mismatch is risky because reviewers and users may trust the skill description while overlooking the actual execution flow, including extra script execution, network retrieval, and deletion steps.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
91% confidence
Finding

The skill instructs network access and file operations but does not declare any tool scope or permissions boundaries. This is dangerous because it obscures the skill's effective capabilities from reviewers and users, increasing the chance that network fetches and filesystem side effects occur without explicit authorization or oversight.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The skill tells the agent to download remote images and later delete temporary files without warning the user that network access and local filesystem changes will occur. This is dangerous because it can cause silent outbound requests to attacker-controlled URLs and unexpected file operations, which can leak metadata or create trust and safety issues even if the downloaded content is only an image.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

Recommending rm <file_path> as cleanup without strong constraints or user warning creates a command-injection and unintended-deletion risk if the path is malformed, attacker-influenced, or points outside the intended temporary directory. In this skill's context, downloaded filenames may derive from untrusted URLs, making deletion behavior more dangerous than ordinary local cleanup guidance.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.