Back to skill

Security audit

Filtrix Image Gen

Security checks for vulnerabilities and agentic risk

Overview

The skill appears to provide the advertised Filtrix image generation/editing flow, but it needs review because its endpoint override can send the API key and user image data to an arbitrary URL.

Review before installing. Use a dedicated Filtrix API key with limited privileges or credits, do not set FILTRIX_MCP_URL unless it is a trusted HTTPS endpoint, and avoid sending private screenshots, IDs, proprietary images, or regulated data unless you accept Filtrix processing them remotely. Save outputs only to intended paths and be aware returned downloads are not size- or type-checked.

Vulnerability Patterns
  • 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
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (2)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/generate.py:186
Finding

Unrestricted MCP Endpoint Override Exposes Credentials and User Content

Content
View full analysis
dict[str, Any]: body = json.dumps(payload).encode("utf-8") headers = { "Authorization": f"Bearer {self.api_key}", "Content-Type": "application/json", "Accept": "application/json, text/event-stream", } if self.session_id: headers["mcp-session-id"] = self.session_id req = urllib.request.Request(self.endpoint, data=body, headers=headers, method="POST") ``` ```python mcp_api_key = os.environ.get("FILTRIX_MCP_API_KEY") or os.environ.get("MCP_API_KEY") if not mcp_api_key: print("ERROR: FILTRIX_MCP_API_KEY is required", file=sys.stderr) sys.exit(1) mcp_url = os.environ.get("FILTRIX_MCP_URL", DEFAULT_MCP_URL) request_key = args.idempotency_key or f"gen-{uuid.uuid4().hex}" client = McpClient(endpoint=mcp_url, api_key=mcp_api_key) ``` The equivalent behavior appears in `scripts/edit.py`: ```python mcp_api_key = os.environ.get("FILTRIX_MCP_API_KEY") or os.environ.get("MCP_API_KEY") if not mcp_api_key: print("ERROR: FILTRIX_MCP_API_KEY is required", file=sys.stderr) sys.exit(1) mcp_url = os.environ.get("FILTRIX_MCP_URL", DEFAULT_MCP_URL) request_key = args.idempotency_key or f"edit-{uuid.uuid4().hex}" client = McpClient(endpoint=mcp_url, api_key=mcp_api_key) ``` ### Technical Analysis The scripts intentionally support `FILTRIX_MCP_URL` as an endpoint override, but they do not validate its scheme, hostna ...[truncated 2569 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/generate.py:148
Finding

Unvalidated Server-Supplied Image URL Enables Arbitrary Outbound Requests and Unbounded Downloads

Content
View full analysis
bytes: req = urllib.request.Request(url, method="GET") try: with urllib.request.urlopen(req, timeout=120) as resp: return resp.read() except urllib.error.HTTPError as exc: raise RuntimeError(f"Signed URL HTTP {exc.code}: {exc.read().decode('utf-8', errors='replace')}") except urllib.error.URLError as exc: raise RuntimeError(f"Signed URL network error: {exc.reason}") ``` ```python image_url = tool_payload.get("image_url") if not isinstance(image_url, str) or not image_url: print(f"ERROR: MCP did not return image_url: {json.dumps(tool_payload, ensure_ascii=False)}", file=sys.stderr) sys.exit(1) try: image_bytes = download_image(image_url) except RuntimeError as exc: print(f"ERROR: {exc}", file=sys.stderr) sys.exit(1) if not args.output: ts = datetime.now().strftime("%Y%m%d_%H%M%S") args.output = f"/tmp/filtrix_mcp_{args.mode}_{ts}.png" out_path = Path(args.output) out_path.parent.mkdir(parents=True, exist_ok=True) out_path.write_bytes(image_bytes) ``` `scripts/edit.py` uses the same unrestricted downloader: ```python def download_image(url: str) -> bytes: req = urllib.request.Request(url, method="GET") try: with urllib.request.urlopen(req, timeout=120) as resp: return resp.read() except urllib.error.HTTPError as exc: raise RuntimeError(f"Signed URL HTTP {exc.code}: {exc.read().decode('utf-8', errors='replace')}") except urllib.error.URLError as exc: raise RuntimeError(f"Signed URL network error: {exc.reason}") ``` ### Technical Analysis Both scripts trust the `image_url` returned by ...[truncated 2748 chars]
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • 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
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (7)

Tp4

High
Category
MCP Tool Poisoning
Confidence
89% confidence
Finding

The skill claims image editing/generation functionality, but the documented flow includes downloading image data from signed URLs and writing it to the local filesystem without clearly stating that behavior. Hidden download-and-write behavior can lead to data persistence, overwriting files, or importing untrusted remote content in contexts where users only expected a transient image transformation request.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
93% confidence
Finding

The skill claims image editing/generation functionality, but the documented flow includes downloading image data from signed URLs and writing it to the local filesystem without clearly stating that behavior. Hidden download-and-write behavior can lead to data persistence, overwriting files, or importing untrusted remote content in contexts where users only expected a transient image transformation request.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
90% confidence
Finding

The skill invokes remote MCP tools, uses environment-based authentication, and documents scripts that read input images and write outputs locally, but it does not declare any explicit tool scope such as permissions or allowed-tools. This creates an avoidable over-privilege and transparency problem: an agent may grant broader capabilities than users expect, increasing the chance of unintended file, network, or secret access.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The skill states a third-party MCP endpoint and API key are used, but it does not clearly warn that user prompts and supplied image inputs may be transmitted off-platform to that remote service. In an image-editing context this is especially important because prompts and images may contain sensitive personal, proprietary, or regulated data.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The documentation explicitly supports sending either an external image URL or raw/base64 image content to a remote MCP endpoint, but it does not warn that user-supplied images will leave the local environment and be transmitted to a third-party service. This creates a privacy and data-handling risk because users or downstream agents may unknowingly upload sensitive images, screenshots, IDs, or internal material to Filtrix.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

When a local image is provided, the script base64-encodes it and sends the contents to a remote MCP endpoint, but the CLI does not clearly warn the user that image data will leave the local machine. This can cause unintended disclosure of sensitive images or embedded metadata, especially because the endpoint is configurable via environment variable and the tool is designed for routine use.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The manifest says the skill can both create images and refine existing ones, implying some image-editing capability. In this file, the only MCP tool invoked is generate_image_text, and there is no code path for accepting an existing image or performing edits/refinements on one.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.