Back to skill

Security audit

Image Scanner Pro

Security checks for vulnerabilities and agentic risk

Overview

This skill does what it claims, but users should understand that selected photos may be sent to Google's Gemini API and that its dependency setup needs cleanup.

Install only if you are comfortable sending the chosen image files to Google's Gemini service for analysis. Prefer GEMINI_API_KEY over the --api-key command-line option, avoid scanning folders containing private or regulated images, and review or update the dependency lockfile before using it in a sensitive environment.

Vulnerability Patterns
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • 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 (2)

T09 · Insecure Skill Coding Practices

Warning
Location
SKILL.md:28
Finding
Gemini API Key Exposed Through Command-Line Arguments<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md:28`; related implementation in `index.js:189-195` **Vulnerability Type**: Command-line credential exposure **Risk Level**: Medium ### Vulnerable Code `SKILL.md:28`: ```bash node skills/image-scanner-pro/index.js --path <directory-path> --api-key <Gemini-Key> --output report.json ``` `index.js:189-195`: ```js const apiKeyIndex = args.indexOf('--api-key'); const proxyIndex = args.indexOf('--proxy'); const modelIndex = args.indexOf('--model'); const outputIndex = args.indexOf('--output'); const dirPath = pathIndex !== -1 ? args[pathIndex + 1] : '.'; const apiKey = apiKeyIndex !== -1 ? args[apiKeyIndex + 1] : process.env.GEMINI_API_KEY; ``` ### Technical Analysis The documented usage instructs users to provide the Gemini API key as a command-line argument. The implementation then retrieves that credential directly from `process.argv`. Command-line arguments are not an appropriate secret-transport mechanism. Depending on the operating system and execution environment, they may be exposed through: - Shell history files. - Process inspection tools and process listings. - `/proc` process metadata on supported systems. - CI/CD command logs. - Terminal recording and diagnostic telemetry. - Wrapper scripts or job-management interfaces that retain submitted commands. Although the application does not print the key itself, accepting and documenting `--api-key` unnecessarily exposes it outside the process. ### Attack Path 1. A user follows the documented command and supplies a valid Gemini API key using `--api-key`. 2. The shell records the complete command in its history, or the operating system exposes the argument through process metadata while the program is running. 3. A local user, support process, monitoring agent, or party with access to CI/CD logs reads the argument. 4. The party extracts the Gemini API key. 5. The stolen credential is used to submit requests to the Gemini API until it is re ...[truncated 821 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Remove `--api-key` from the documented command and from the command-line parser. 2. Prefer the existing `GEMINI_API_KEY` environment-variable mechanism: ```bash export GEMINI_API_KEY='...' node skills/image-scanner-pro/index.js --path <directory-path> --output report.json ``` 3. For interactive use, obtain the key through a hidden prompt that does not echo input or retain it in shell history. 4. For production and CI/CD environments, load the credential from a dedicated secret manager and inject it only into the child process environment. 5. Ensure CI/CD systems mask the environment variable and prevent it from appearing in debug output. 6. Never include the key in reports, exception messages, process titles, or diagnostic logs. 7. Rotate any key that has previously been supplied through the documented `--api-key` option. 8. Apply API-side restrictions, quotas, and monitoring to reduce the impact of future credential exposure. ]]>

T08 · Insecure Dependencies

Note
Location
package-lock.json:14
Finding
Dependency Lockfile Uses a Third-Party npm Registry Mirror<![CDATA[ ## Vulnerability Details **File Location**: `package-lock.json:14-15`, with equivalent mirror URLs repeated through `package-lock.json:23-330` **Vulnerability Type**: Third-party dependency source and supply-chain exposure **Risk Level**: Low ### Vulnerable Code Representative locked dependency entry from `package-lock.json:14-15`: ```json "resolved": "https://registry.npmmirror.com/@google/generative-ai/-/generative-ai-0.24.1.tgz", "integrity": "sha512-MqO+MLfM6kjxcKoy0p1wRzG3b4ZZXtPI+z2IE26UogS2Cm/XHO+7gGRBh6gcJsOiIVoH93UwKvW4HdgiOZCy9Q==", ``` The lockfile uses `https://registry.npmmirror.com/` for the direct dependencies and their transitive dependencies rather than the official npm registry. ### Technical Analysis The committed lockfile directs package installation to a third-party npm mirror. This adds the mirror operator and its infrastructure to the project's dependency trust and availability chain. The recorded SHA-512 integrity values significantly reduce the risk that the mirror can silently replace an already locked package with arbitrary content: npm should reject a downloaded archive whose hash does not match the lockfile. Consequently, compromise of the mirror alone is generally insufficient to alter the currently locked artifacts without also changing the trusted lockfile or producing content matching the recorded hash. Residual risks remain in the following circumstances: - The mirror is compromised or serves malicious content while dependencies or the lockfile are being created or updated. - A malicious lockfile modification changes both the resolved URL and integrity value. - Installation availability depends on the third-party mirror remaining reachable. - Reviewers assume packages originate directly from the official npm registry when the lockfile specifies otherwise. The project also declares `proxy-agent` in `package.json`, but the audited application code does not import it. Removing unnecessary dependencies would redu ...[truncated 1782 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Configure npm to use the official registry: ```bash npm config set registry https://registry.npmjs.org/ ``` 2. Regenerate and review the lockfile using the trusted registry: ```bash rm -rf node_modules package-lock.json npm install ``` 3. Verify that all regenerated `resolved` fields use the approved registry and that integrity hashes remain present. 4. Require code review for changes to dependency versions, `resolved` URLs, and integrity values. 5. Pin reviewed dependency versions where reproducibility is important, rather than relying only on broad semver ranges. 6. Run dependency vulnerability and provenance checks in CI/CD. 7. Restrict automated dependency updates to approved registries and trusted update services. 8. Remove `proxy-agent` if it is not required, because `index.js` does not import it and its transitive dependencies unnecessarily increase the supply-chain surface. 9. If organizational policy requires a mirror, use an organization-controlled, authenticated repository proxy with upstream verification, immutability, access logging, and artifact scanning. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (9)

Missing User Warnings

High
Confidence
97% confidence
Finding
The description says the skill scans image folders and analyzes photos with Gemini 2.0 Flash, but it does not warn users that image contents will be transmitted to a third-party vision API. This omission is dangerous because users may expose sensitive personal, confidential, or regulated image data without informed consent.

Known Vulnerable Dependency: basic-ftp==5.2.0 — 4 advisory(ies): GHSA-6v7q-wjvx-w8wg (basic-ftp: Incomplete CRLF Injection Protection Allows Arbitrary FTP Command Exe); CVE-2026-39983 (basic-ftp has FTP Command Injection via CRLF); CVE-2026-41324 (basic-ftp vulnerable to denial of service via unbounded memory consumption in Cl) +1 more

High
Category
Supply Chain
Confidence
91% confidence
Finding
The lockfile pins basic-ftp to 5.2.0, and the reported advisories include FTP command injection via incomplete CRLF sanitization and denial-of-service conditions. Even though this file is only a dependency manifest, shipping a known-vulnerable version is a real supply-chain risk because any code path that uses FTP URLs or proxy resolution through this package chain could expose the application to attacker-controlled input.

Known Vulnerable Dependency: ip-address==10.1.0 — 2 advisory(ies): CVE-2026-69192 (ip-address: Address4 decodes leading-zero octets as decimal while resolvers deco); CVE-2026-42338 (ip-address has XSS in Address6 HTML-emitting methods)

High
Category
Supply Chain
Confidence
80% confidence
Finding
The lockfile includes ip-address 10.1.0, which is reported as affected by address parsing inconsistencies and XSS in HTML-emitting methods. This is a real dependency risk, but the practical impact depends on whether the application renders output from the library into HTML or relies on strict canonical IP parsing for security decisions; in this image-scanning context, it is less obviously exposed than the FTP issue.

Vague Triggers

Medium
Confidence
93% confidence
Finding
The trigger phrases are generic enough to match ordinary requests like image recognition, photo analysis, or portfolio organization, which can cause the skill to activate unexpectedly. Because this skill processes local image folders and sends images to an external model, ambiguous invocation increases the chance of unintentional data exposure and execution outside the user's intended scope.

Natural-Language Policy Violations

Medium
Confidence
96% confidence
Finding
The embedded prompt instructs the model entirely in Chinese and specifies Chinese output labels, which imposes a language choice on all users. There is no visible option to select another language or to opt in to this locale behavior.

Missing User Warnings

Medium
Confidence
96% confidence
Finding
When an API key is configured, the code reads each local image, base64-encodes it, and sends the full image content to Google's Gemini service. The tool logs model/proxy settings but does not provide an explicit consent gate or clear user-facing warning that local image contents may leave the machine, which is risky because photos often contain sensitive personal, location, or business information.

Natural-Language Policy Violations

Low
Confidence
82% confidence
Finding
All user-facing natural-language content in the skill file is Chinese, and the file does not indicate that this language choice is optional or limited to a justified region-specific use case. This can violate a language or locale policy when users are not given an explicit opt-in or alternative.

Unpinned Dependencies

Low
Category
Supply Chain
Content
{
  "dependencies": {
    "@google/generative-ai": "^0.24.1",
    "proxy-agent": "^6.5.0"
  }
}
Confidence
95% confidence
Finding
The dependency uses a caret range (^0.24.1), which permits automatic installation of newer compatible versions instead of a single audited release. This creates supply-chain risk because a newly published upstream version could introduce malicious code or a breaking security regression without an explicit review in this skill.

Unpinned Dependencies

Low
Category
Supply Chain
Content
{
  "dependencies": {
    "@google/generative-ai": "^0.24.1",
    "proxy-agent": "^6.5.0"
  }
}
Confidence
95% confidence
Finding
The dependency uses a caret range (^6.5.0), allowing future package versions to be resolved during install rather than a single known-good version. For a network-related package such as proxy-agent, this increases supply-chain exposure because compromised or vulnerable upstream releases could affect traffic handling or execution behavior unexpectedly.

Static analysis

No suspicious patterns detected.