Back to skill

Security audit

Nano Banana Openrouter

Security checks for vulnerabilities and agentic risk

Overview

The skill mostly does what it claims, but it handles API keys unsafely and can send the wrong provider's credential to OpenRouter.

Review before installing. Use only an OpenRouter-specific API key, remove or ignore the bundled test script with the hardcoded key, and do not include secrets, private data, or regulated content in image prompts because prompts are sent to OpenRouter. The GEMINI_API_KEY fallback should be removed before normal use.

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

T09 · Insecure Skill Coding Practices

Error
Location
test-gen.mjs:3
Finding

Hard-Coded OpenRouter API Credential in Test Script

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
index.ts:20
Finding

Gemini Credential Can Be Forwarded to OpenRouter

Content
View full analysis
Remediation
View remediation

T08 · Insecure Dependencies

Note
Location
package-lock.json:17
Finding

Dependency Lockfile Uses a Non-Default Registry Mirror

Content
View full analysis
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • YARA SignaturesMalware Match, Webshell Match, Cryptominer Match
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (11)

YARA rule 'privilege_escalation_tools': Privilege escalation tools and techniques [hacktools]

High
Category
YARA Match
Confidence
75% confidence
Finding

YARA rule matched a hack tool or exploit indicator (offensive tools, reconnaissance, privilege escalation, or exploit frameworks).

Content

Scanner excerpt · output.json (reported line 24)May include surrounding context.

json
XYwnOyen50rOPHh7Dv9ZNr8q6HD/kmwGcEeCzKEovtnctcZQ57Wns8Pd2yiwbzsmPnMY0TApF/VrIapM+cRqWkbxYJWACzqjzHeCwh7bOwOUJmaiGVVgfD4Gdq7542tTviKj49N5bdKSjq7kaRILKTzXebU2AR4+Sz+WTxtkPoCvEs/CQQCHRwYIfH8nOjdKROe7sSMdvxX9DmoudaHlxceY+e6c0pawIk/Rz+kqWg49UyV7dqK8Bi71Z+4fR4UyXhttLH2r1x02b+aq1QuZDA2InQixM8b+7dSNaJKdpmlXraEoqxFkvFVGdpS90ThnPd/nTuKnCXClB40Tr0Xqfx7SGEGJBLda4T71LG2d0WL7fT052Mr4YU5eHNhXI61RX0dWKcjy90iC2qmcpsPyTUYHvl7OxSPsvHNiiRSxfNjQjdruha2MPlD7F9tD5dKwlc2HjP/HRhIs/G3kwSj1/00sx3mQF9WZcu0xWbxdL/YrNglVVZWXBI2b3ZEyv0iS//yv6ZVVTKN1yOIrPYqA48YGwO216t9vZrDYR8viOW+PXNAtdXbOitWJTtRAo0Vq2iAFmuWIwyry+Gp8UDgdRgOYhldONdTo5v8GnRDvvZzNkIMh2+BK4z6lpIuasefIv1Zu1YDLEkORu4lt6Fz5gTXTJwRCkPtcBDzpEL2cM6oSdhlmrlsHKhr1gGvqKnOIhvgPQB7rkpWUtHOyfyBmLpcUCMrNbJYUf7I7h8ccrYMDpVZv39uXF9vwdefKxwIBAIdBE0P3AN1KmS65TCGDjEFShUSfiA4GbPBBR4LqZC0ukaPCA3rfw/uUI2fNKc6h1nDBE0eqSSTGWiazb3cvXaZSCoAyr57iqFXfaJ1zCs1lbeEdT1hBQB844onmP321Up5IBAIfCWODZWxvBnoQ2VF+OmGaEJvwRWHjzkD+4nkGQEPN1G2rNGu6RdmWy8Y5ueg6bzsAWDvsmrD6x1qeHYzg6ZIZOGQlHdJ6l9AH

External Transmission

Medium
Category
Data Exfiltration
Confidence
90% confidence
Finding

This code performs an outbound network request to a third-party API and includes user-controlled prompt content in the request body. External transmission is not inherently malicious, but in this skill context it becomes security-relevant because there is no validation, warning, or policy control around what data the agent may exfiltrate to the remote service.

Content

Scanner excerpt · index.ts (reported line 27)May include surrounding context.

ts
// OpenRouter Chat Completions Endpoint for Image Generation
  // Note: Gemini 2.5 Flash Image uses 'modalities: ["image"]' in the request body
  const response = await fetch("https://openrouter.ai/api/v1/chat/completions", {
    method: "POST",
    headers: {
      "Authorization": `Bearer ${apiKey}`,

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The tool sends the user-supplied prompt, including any embedded sensitive or proprietary text, to OpenRouter without any disclosure in the tool metadata that prompt contents leave the local environment. In an agent setting, users may reasonably assume prompts are handled internally, so undisclosed third-party transmission creates a real privacy and data-handling risk even though the behavior appears functionally intended.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
90% confidence
Finding

This code performs an external network transmission to a third-party API, which is security-relevant because it moves generated content and request metadata outside the local trust boundary. While external calls can be legitimate, in this file they are paired with a hardcoded credential and no guardrails around what may be transmitted.

Content

Scanner excerpt · test-gen.mjs (reported line 8)May include surrounding context.

js
async function generate() {
  console.log("Generating logo...");
  try {
    const response = await fetch("https://openrouter.ai/api/v1/chat/completions", {
      method: "POST",
      headers: {
        "Authorization": `Bearer ${apiKey}`,

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The file makes a hardcoded outbound call to a third-party model API and embeds a live bearer credential directly in source. This creates two concrete risks: unauthorized external transmission of prompt content to an unvetted service and immediate credential compromise if the code is shared, logged, or committed to a repository.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The skill sends prompt content and an authorization credential to an external provider without any meaningful disclosure, consent flow, or data-handling notice beyond a generic log line. In agent contexts, this can cause users or operators to unknowingly exfiltrate sensitive business data, prompts, or proprietary content to a third party.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
94% confidence
Finding

The dependency uses a caret range (^3.3.2), which permits automatic installation of newer minor/patch releases. This creates supply-chain risk because a compromised or breaking upstream release could be pulled in without an explicit review, though the package itself is common and there is no direct evidence of malicious intent in this file.

Content

Scanner excerpt · package.json (reported line 12)May include surrounding context.

json
"start": "node index.js"
  },
  "dependencies": {
    "node-fetch": "^3.3.2"
  },
  "devDependencies": {
    "@types/node": "^20.0.0",

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
89% confidence
Finding

The development dependency @types/node is specified with a caret range, allowing unreviewed updates within the major version. While this is lower risk than a runtime package because it is primarily used during development/build time, it still introduces supply-chain exposure and build reproducibility issues.

Content

Scanner excerpt · package.json (reported line 15)May include surrounding context.

json
"node-fetch": "^3.3.2"
  },
  "devDependencies": {
    "@types/node": "^20.0.0",
    "typescript": "^5.0.0"
  }
}

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
90% confidence
Finding

The TypeScript compiler dependency is also unpinned via a caret range, so newer releases can be installed automatically. A compromised or incompatible compiler release could affect builds, generated output, or CI pipelines, even if it is not shipped directly at runtime.

Content

Scanner excerpt · package.json (reported line 16)May include surrounding context.

json
},
  "devDependencies": {
    "@types/node": "^20.0.0",
    "typescript": "^5.0.0"
  }
}

Intent-Code Divergence

Low
Category
Not specified by scanner
Confidence
89% confidence
Finding

The comments at L11, L17, and L22 say the intent is to inspect the output.json structure and dump keys to locate image data. However, once image data is found, the script proceeds to decode base64 and write logo.png to disk at L33, which is a materially different side effect than the documented inspection/debugging intent.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Low
Category
Not specified by scanner
Confidence
70% confidence
Finding

The inline console message frames the action as simply 'Generating logo...', but the actual request sends a detailed prompt to a remote multimodal model to design branded visual content. This is a mild intent/documentation divergence because the code is not merely performing a local logo-rendering step; it is delegating creative generation to an external service.

Content

No source excerpt is available for this finding.

Static analysis

Detected: suspicious.env_credential_access, suspicious.exposed_secret_literal

Environment variable access combined with network send.

Critical
Code
suspicious.env_credential_access
Location
index.ts:20

File appears to expose a hardcoded API secret or token.

Critical
Code
suspicious.exposed_secret_literal
Location
test-gen.mjs:3