Back to skill

Security audit

Google SERP Hotels Search API

Security checks for vulnerabilities and agentic risk

Overview

This is a narrow hotel-search API wrapper that sends disclosed search parameters to Just Serp API, with no hidden persistence or destructive behavior found.

Install only if you are comfortable sending hotel search details to Just Serp API. Protect and scope the JUST_SERP_API_KEY where possible, because the current helper invocation places it in the command-line arguments during execution.

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
SKILL.md:66
Finding

API Key Exposure Through Command-Line Arguments

Content
View full analysis

Vulnerability Details

File Location: SKILL.md:66,74 and bin/run.mjs:294,309,376-378
Vulnerability Type: Sensitive credential exposure through the process argument vector
Risk Level: Medium

Vulnerable Code

SKILL.md:66

bash
node {baseDir}/bin/run.mjs --operation "hotelsSearch" --api-key "$JUST_SERP_API_KEY" --params-json '{"query":"<query>","check_in_date":"<check_in_date>","check_out_date":"<check_out_date>"}'

SKILL.md:74

markdown
- Pass the API key with `--api-key "$JUST_SERP_API_KEY"`; do not paste key values into chat messages, screenshots, or logs.

bin/run.mjs:294

js
if (!args.apiKey) {
  fail("Missing required --api-key argument.");
}

bin/run.mjs:306-311

js
const requestInit = {
  headers: {
    "accept": "application/json",
    "X-API-Key": args.apiKey,
  },
  method: operation.method,
};

bin/run.mjs:376-379

js
if (flag === "--api-key") {
  parsed.apiKey = value;
  index += 1;
  continue;
}

Technical Analysis

The documented invocation expands JUST_SERP_API_KEY into a command-line argument. Consequently, the credential may be present in the Node process argument vector for the lifetime of the process.

Depending on operating-system configuration and local permissions, command-line arguments may be observable through process-listing utilities, process monitoring, telemetry, diagnostic collection, shell tracing, or audit infrastructure. HTTPS protects the credential while it is transmitted to the fixed API endpoint, but it does not protect the credential from local disclosure before transmission.

The network transmission itself is consistent with the Skill's declared functionality: bin/run.mjs sends the API key in the X-API-Key header to the fixed HTTPS host api.justserpapi.com. The weakness is the command-line transport used to supply that key to the script.

Attack Path

  1. A user invokes the Skill according to SKILL.md, causing the shell to replace `$JUST_SE ...[truncated 1091 chars]
Remediation
View remediation

Remediation Suggestions

  1. Read the credential directly from the environment inside bin/run.mjs instead of requiring it as an argument:
js
const apiKey = process.env.JUST_SERP_API_KEY;

if (!apiKey) {
  fail("Missing required JUST_SERP_API_KEY environment variable.");
}

const requestInit = {
  headers: {
    accept: "application/json",
    "X-API-Key": apiKey,
  },
  method: operation.method,
};
  1. Remove --api-key parsing and update SKILL.md so the command does not expand the secret into the argument vector:
bash
JUST_SERP_API_KEY="$JUST_SERP_API_KEY" \
node {baseDir}/bin/run.mjs \
  --operation "hotelsSearch" \
  --params-json '{"query":"<query>","check_in_date":"<check_in_date>","check_out_date":"<check_out_date>"}'
  1. Where stronger isolation is required, accept the secret through a protected file descriptor or a permission-restricted secret file supplied by the runtime.

  2. Ensure error messages, telemetry, shell tracing, and diagnostic output never include request headers or the credential.

  3. Scope and rotate the API key, enforce quotas where supported, and revoke any key suspected of having appeared in process-monitoring records.

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
92% confidence
Finding

The skill invokes a network-capable helper (node {baseDir}/bin/run.mjs) to call an external API, but the manifest does not explicitly declare tool scope via permissions or allowed-tools. This creates a transparency and policy-enforcement gap: a host may allow broader execution or users may not realize the skill can make outbound requests with user-supplied parameters and an API key.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

This code sends query parameters such as destination, dates, occupancy, and optional children ages to a third-party endpoint via fetch. There is no confirmation prompt, user-facing log, or inline warning near the network operation to disclose that user travel-related data will be transmitted externally.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

This skill sends user-supplied hotel search inputs to a third-party API, including travel dates, destination, occupancy, children counts, and children ages, without any visible disclosure in the manifest that potentially sensitive travel data will leave the platform. While this is expected for the feature to function, the lack of transparent user-facing notice increases privacy risk because travel itinerary and family composition data can be sensitive and may be shared unknowingly with an external service.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
81% confidence
Finding

Lines L27-L28 instruct callers to set result language and target country, which is natural-language guidance affecting locale behavior. The file does not mention that these localization settings should be chosen based on user preference or explicit opt-in, so it can encourage forced locale selection.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.