Back to skill

Security audit

Google SERP Lens API

Security checks for vulnerabilities and agentic risk

Overview

This is a focused Google Lens API wrapper that sends a public image URL to Just Serp API; the main caution is weaker API-key handling in the documented command.

Install only if you are comfortable sending the specified public image URL and query options to Just Serp API for Google Lens results. Avoid sensitive or private image URLs, and prefer changing the helper to read JUST_SERP_API_KEY directly from the environment instead of passing it on the command line; rotate the key if it has been used where process arguments may be logged or visible.

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
bin/run.mjs:182
Finding

API Key Exposed Through Command-Line Arguments

Content
View full analysis

Vulnerability Details

File Location: bin/run.mjs:113-114, 129, 182-198; documented usage in SKILL.md:46, 54
Vulnerability Type: Sensitive credential exposure through process arguments
Risk Level: Medium

Vulnerable Code

js
if (!args.apiKey) {
  fail("Missing required --api-key argument.");
}
js
const requestInit = {
  headers: {
    "accept": "application/json",
    "X-API-Key": args.apiKey,
  },
  method: operation.method,
};
js
function parseArgs(argv) {
  const parsed = { apiKey: null, operation: null, paramsJson: "{}" };
  for (let index = 0; index < argv.length; index += 1) {
    const flag = argv[index];
    const value = argv[index + 1];

    // ...

    if (flag === "--api-key") {
      parsed.apiKey = value;
      index += 1;
      continue;
    }
    fail(`Unknown argument "${flag}".`);
  }
  return parsed;
}

The corresponding documented invocation is:

bash
node {baseDir}/bin/run.mjs --operation "lens" --api-key "$JUST_SERP_API_KEY" --params-json '{"url":"<url>"}'

Technical Analysis

The helper requires the API key to be supplied using the --api-key command-line option. Although the shell expression references an environment variable, the shell expands that variable before starting Node.js. The resulting plaintext key is therefore placed in the process argument vector.

Process arguments may be visible to other local users, privileged monitoring agents, process inspection utilities, audit systems, diagnostic collectors, or command-line telemetry, depending on the operating system and deployment configuration. The documentation's warning not to paste or log the key does not prevent this exposure because the prescribed invocation itself transfers the secret into process arguments.

The key is legitimately sent to the fixed HTTPS API endpoint in the X-API-Key header; that behavior is not itself th ...[truncated 1257 chars]

Remediation
View remediation

Remediation Suggestions

  1. Read the credential directly from the environment rather than accepting it as a command-line argument:

    js
    const apiKey = process.env.JUST_SERP_API_KEY;
    
    if (!apiKey) {
      fail("Missing required JUST_SERP_API_KEY environment variable.");
    }
    
  2. Use the environment-derived value only when constructing the authentication header:

    js
    const requestInit = {
      headers: {
        accept: "application/json",
        "X-API-Key": apiKey,
      },
      method: operation.method,
    };
    
  3. Remove --api-key handling from parseArgs so users cannot accidentally place credentials in the process argument vector.

  4. Update SKILL.md to document invocation without a credential argument:

    bash
    JUST_SERP_API_KEY="$JUST_SERP_API_KEY" \
      node {baseDir}/bin/run.mjs \
      --operation "lens" \
      --params-json '{"url":"<url>"}'
    

    If the environment variable is already exported, omit the inline assignment entirely.

  5. For higher-assurance environments, retrieve the key from a dedicated secret manager or protected file descriptor and ensure that errors, debug logs, and telemetry never serialize authentication headers or secret values.

  6. Rotate the existing API key if the documented command has been used in an environment where process arguments or command-line telemetry may have been accessible to unauthorized parties.

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

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
92% confidence
Finding

The skill invokes a network-capable helper (node .../bin/run.mjs) and accepts a user-supplied url, but it does not declare any explicit tool scope such as allowed network access or permissions. This weakens policy enforcement and reviewability because an agent may make outbound requests without a clearly constrained permission model, increasing the risk of unintended external access or misuse of the provided URL parameter.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
84% confidence
Finding

This code performs a network request to a third-party service using a user-provided image URL as query data and an API key in headers. There is no confirmation prompt, user-facing log, or inline warning explaining that input data will be transmitted off-system to an external API.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.