Back to skill

Security audit

Automatic Number Plate Recognition

Security checks for vulnerabilities and agentic risk

Overview

The skill does what it claims, but it can upload sensitive vehicle images and an API key to any configured URL without HTTPS or host safeguards.

Review this skill before installing. It is not evidence of malware, but use it only with images you are willing to send to TrafficEye or a configured endpoint, keep `TRAFFICEYE_API_URL` pinned to a trusted HTTPS host, avoid query-string API keys, and do not run it in an environment where untrusted configuration can change the endpoint.

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 (1)

T09 · Insecure Skill Coding Practices

Warning
Location
recognize_plate.py:256
Finding

Unrestricted API Endpoint Allows Sensitive Image and Credential Disclosure

Content
View full analysis
str: """Append the API key to the query string when query-mode auth is enabled.""" if api_key_mode != "query" or not api_key: return api_url parsed = urllib.parse.urlsplit(api_url) query_items = urllib.parse.parse_qsl(parsed.query, keep_blank_values=True) query_items.append((api_key_name, api_key)) updated_query = urllib.parse.urlencode(query_items) return urllib.parse.urlunsplit((parsed.scheme, parsed.netloc, parsed.path, updated_query, parsed.fragment)) def call_api( image_path: Path, api_url: str, api_key: str | None, api_key_mode: str, api_key_name: str, request_json: str | None, file_field: str, request_field: str, timeout_s: float, ) -> Any: """Upload the image to the API and parse the JSON response.""" fields: dict[str, str | bytes] = {} if request_json: fields[request_field] = request_json if api_key_mode == "form" and api_key: fields[api_key_name] = api_key image_bytes = image_path.read_bytes() body, content_type = build_multipart_body( fields, {file_field: (image_path.name, image_bytes, None)}, ) request_url = build_request_url(api_url, api_key, api_key_mode, api_key_name) headers = {"Content-Type": content_type, "Content-Length": str(len(body))} if api_key_mode == "header" and api_key: headers[api_key_name] = api_key elif api_key_mode == "bearer" and api_key: headers["Authorization"] = f"Bearer {api_key}" request = urllib.request.Request(request_url, data=body, headers=headers, method="POST") try: with urllib.request.urlopen(request, timeout=timeou ...[truncated 3388 chars]
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
Findings (4)

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
96% confidence
Finding

The skill requires environment access, local file access, and outbound network access but does not declare any explicit tool scope or allowed-tools boundary. This weakens least-privilege controls and makes it easier for an agent runtime to invoke the skill without clear permission review, increasing the chance that sensitive local files or secrets are accessed and transmitted unexpectedly.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The skill sends a local image to a third-party API for processing, but the user-facing description and workflow do not clearly warn that image contents, including potentially sensitive location, vehicle, or personal data, leave the local environment. Because license plate images often contain regulated or identifying information, the missing disclosure meaningfully raises privacy and consent risk.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The skill reads a local image file and uploads its raw contents to a third-party API, but the code provides no user-facing disclosure, confirmation step, or guardrail indicating that local data will leave the host. In this skill context, that is a real privacy/security issue because vehicle images and license plates are sensitive data, and users may reasonably expect local OCR-style processing unless outbound transmission is made explicit.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
80% confidence
Finding

The script accesses a sensitive credential from TRAFFICEYE_API_KEY and uses it for authentication, but there is no user-facing warning or explanatory comment around credential handling. Under the rule, access to sensitive environment variables should have some form of disclosure unless clearly documented elsewhere.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.