Back to skill

Security audit

api-gateway

Security checks for vulnerabilities and agentic risk

Overview

This API gateway is mostly purpose-aligned, but it can persist sensitive request bodies in cache keys despite claiming metadata-only caching and its network allowlist is narrower in the documentation than in the implementation.

Review this before installing. Use it only for endpoints you explicitly trust, avoid sending secrets or regulated data in request bodies, and clear cache/logs after sensitive work. Do not rely on the metadata-only cache claim in this version: request body contents may be written into cache.json by default. Prefer scoped environment variables or a secrets manager for keys, and treat the whole memory/api-gateway directory as sensitive local storage.

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
api-gateway.js:385
Finding

Sensitive Request Bodies Are Persisted in Metadata-Only Cache Keys

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
api-gateway.js:171
Finding

Provider Allowlist Does Not Restrict Network Destinations or Request-Body Transmission

Content
View full analysis
{ // SECURITY: enforce HTTPS. Plain HTTP can expose bearer tokens / API keys // on the wire, so we refuse non-https endpoints unless explicitly opted in. if (!url.startsWith('https://')) { if (process.env.API_GATEWAY_ALLOW_HTTP !== '1') { return reject(new Error( `[api-gateway] REFUSED non-HTTPS request to "${url}". ` + `API Gateway only sends requests over HTTPS to protect credentials. ` + `If you must call a plaintext endpoint, set API_GATEWAY_ALLOW_HTTP=1 (not recommended for any call that attaches a key).` )); } console.log(`[api-gateway] ⚠️ SECURITY WARNING: sending request over plain HTTP to "${url}" (API_GATEWAY_ALLOW_HTTP=1). Credentials are NOT encrypted on the wire.`); } const isHttps = url.startsWith('https'); const client = isHttps ? https : http; const options = { hostname: new URL(url).hostname, port: new URL(url).port || (isHttps ? 443 : 80), path: new URL(url).pathname + new URL(url).search, method, headers: { 'Content-Type': 'application/json', ...headers }, timeout }; const req = client.request(options, (res) => { ``` For environment-sourced keys, an allowlist mismatch does not terminate the call. It merely suppresses the authorization header: ```javascript let authDecision = shouldAttachAuth(provider, endpoint, keys); if (!authDecision.attach && key ...[truncated 4854 chars]
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
Findings (25)

Env Variable Harvesting

High
Category
Data Exfiltration
Confidence
60% 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 · api-gateway.js (reported line 526)May include surrounding context.

js
const entries = Object.entries(keys);
  
  // Also detect env-var-only providers
  const envProviders = Object.keys(process.env)
    .filter(k => k.endsWith('_API_KEY') && process.env[k])
    .map(k => k.replace(/_API_KEY$/, '').toLowerCase());

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The README advertises external API calls, request logging, and response caching but does not warn that prompts, headers, request bodies, or provider responses may be transmitted to third parties and retained locally. In an agent skill context, users may pass sensitive data through the gateway, so missing disclosure and guidance increases the risk of inadvertent data exposure and retention.

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 · README.md (reported line 44)May include surrounding context.

Make an HTTP request with automatic retry and timeout.

javascript
const result = await AG.makeRequest('https://api.openai.com/v1/models', 'GET', {}, null, 30000);

maskKey(key)

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 · SKILL.md (reported line 50)May include surrounding context.

Make an HTTP request with automatic retry and timeout.

javascript
const result = await AG.makeRequest('https://api.openai.com/v1/models', 'GET', {}, null, 30000);

maskKey(key)

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 · SKILL.md (reported line 58)May include surrounding context.

Make an HTTP request with automatic retry and timeout.

javascript
const result = await AG.makeRequest('https://api.openai.com/v1/models', 'GET', {}, null, 30000);

maskKey(key)

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 · SKILL.md (reported line 78)May include surrounding context.

Make an HTTP request with automatic retry and timeout.

javascript
const result = await AG.makeRequest('https://api.openai.com/v1/models', 'GET', {}, null, 30000);

maskKey(key)

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
80% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

Scanner excerpt · SKILL.md (reported line 3)May include surrounding context.

md
---
name: api-gateway
description: Smart proxy for external API calls with retry, caching, rate limiting, and fallback providers. PERSISTS: API keys (chmod 0600 plaintext in keys.json), request/response cache metadata, and request logs. Network: outbound HTTPS only, with a strict provider-domain allowlist. Caches metadata by default; full response bodies are opt-in per provider.
---

# API Gateway ⚡

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
80% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

Scanner excerpt · SKILL.md (reported line 20)May include surrounding context.

md
---
name: api-gateway
description: Smart proxy for external API calls with retry, caching, rate limiting, and fallback providers. PERSISTS: API keys (chmod 0600 plaintext in keys.json), request/response cache metadata, and request logs. Network: outbound HTTPS only, with a strict provider-domain allowlist. Caches metadata by default; full response bodies are opt-in per provider.
---

# API Gateway ⚡

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
80% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

Scanner excerpt · SKILL.md (reported line 33)May include surrounding context.

md
---
name: api-gateway
description: Smart proxy for external API calls with retry, caching, rate limiting, and fallback providers. PERSISTS: API keys (chmod 0600 plaintext in keys.json), request/response cache metadata, and request logs. Network: outbound HTTPS only, with a strict provider-domain allowlist. Caches metadata by default; full response bodies are opt-in per provider.
---

# API Gateway ⚡

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
80% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

Scanner excerpt · SKILL.md (reported line 154)May include surrounding context.

md
---
name: api-gateway
description: Smart proxy for external API calls with retry, caching, rate limiting, and fallback providers. PERSISTS: API keys (chmod 0600 plaintext in keys.json), request/response cache metadata, and request logs. Network: outbound HTTPS only, with a strict provider-domain allowlist. Caches metadata by default; full response bodies are opt-in per provider.
---

# API Gateway ⚡

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
80% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

Scanner excerpt · SKILL.md (reported line 175)May include surrounding context.

md
---
name: api-gateway
description: Smart proxy for external API calls with retry, caching, rate limiting, and fallback providers. PERSISTS: API keys (chmod 0600 plaintext in keys.json), request/response cache metadata, and request logs. Network: outbound HTTPS only, with a strict provider-domain allowlist. Caches metadata by default; full response bodies are opt-in per provider.
---

# API Gateway ⚡

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
80% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

Scanner excerpt · SKILL.md (reported line 201)May include surrounding context.

md
---
name: api-gateway
description: Smart proxy for external API calls with retry, caching, rate limiting, and fallback providers. PERSISTS: API keys (chmod 0600 plaintext in keys.json), request/response cache metadata, and request logs. Network: outbound HTTPS only, with a strict provider-domain allowlist. Caches metadata by default; full response bodies are opt-in per provider.
---

# API Gateway ⚡

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
80% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

Scanner excerpt · api-gateway.js (reported line 23)May include surrounding context.

js
---
name: api-gateway
description: Smart proxy for external API calls with retry, caching, rate limiting, and fallback providers. PERSISTS: API keys (chmod 0600 plaintext in keys.json), request/response cache metadata, and request logs. Network: outbound HTTPS only, with a strict provider-domain allowlist. Caches metadata by default; full response bodies are opt-in per provider.
---

# API Gateway ⚡

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
80% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

Scanner excerpt · api-gateway.js (reported line 73)May include surrounding context.

js
---
name: api-gateway
description: Smart proxy for external API calls with retry, caching, rate limiting, and fallback providers. PERSISTS: API keys (chmod 0600 plaintext in keys.json), request/response cache metadata, and request logs. Network: outbound HTTPS only, with a strict provider-domain allowlist. Caches metadata by default; full response bodies are opt-in per provider.
---

# API Gateway ⚡

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
80% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

Scanner excerpt · api-gateway.js (reported line 566)May include surrounding context.

js
---
name: api-gateway
description: Smart proxy for external API calls with retry, caching, rate limiting, and fallback providers. PERSISTS: API keys (chmod 0600 plaintext in keys.json), request/response cache metadata, and request logs. Network: outbound HTTPS only, with a strict provider-domain allowlist. Caches metadata by default; full response bodies are opt-in per provider.
---

# API Gateway ⚡

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
80% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

Scanner excerpt · clawhub.yaml (reported line 4)May include surrounding context.

yaml
---
name: api-gateway
description: Smart proxy for external API calls with retry, caching, rate limiting, and fallback providers. PERSISTS: API keys (chmod 0600 plaintext in keys.json), request/response cache metadata, and request logs. Network: outbound HTTPS only, with a strict provider-domain allowlist. Caches metadata by default; full response bodies are opt-in per provider.
---

# API Gateway ⚡

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
80% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

Scanner excerpt · clawhub.yaml (reported line 28)May include surrounding context.

yaml
---
name: api-gateway
description: Smart proxy for external API calls with retry, caching, rate limiting, and fallback providers. PERSISTS: API keys (chmod 0600 plaintext in keys.json), request/response cache metadata, and request logs. Network: outbound HTTPS only, with a strict provider-domain allowlist. Caches metadata by default; full response bodies are opt-in per provider.
---

# API Gateway ⚡

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
80% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

Scanner excerpt · clawhub.yaml (reported line 34)May include surrounding context.

yaml
---
name: api-gateway
description: Smart proxy for external API calls with retry, caching, rate limiting, and fallback providers. PERSISTS: API keys (chmod 0600 plaintext in keys.json), request/response cache metadata, and request logs. Network: outbound HTTPS only, with a strict provider-domain allowlist. Caches metadata by default; full response bodies are opt-in per provider.
---

# API Gateway ⚡

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
80% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

Scanner excerpt · clawhub.yaml (reported line 38)May include surrounding context.

yaml
---
name: api-gateway
description: Smart proxy for external API calls with retry, caching, rate limiting, and fallback providers. PERSISTS: API keys (chmod 0600 plaintext in keys.json), request/response cache metadata, and request logs. Network: outbound HTTPS only, with a strict provider-domain allowlist. Caches metadata by default; full response bodies are opt-in per provider.
---

# API Gateway ⚡

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
86% confidence
Finding

The early description of persisted data understates the sensitivity of what can be written when full-body caching is enabled. Because users often rely on top-level summaries, this can cause them to enable or use the skill under a false assumption that only low-risk metadata is stored, when complete API responses may later be written to disk. For a gateway handling tokens, prompts, and provider responses, understated persistence is a meaningful security weakness.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The documentation is internally inconsistent about what data is persisted. Earlier sections say request logs do not store endpoints or request/response bodies and that cache is metadata-only by default, but the later security note states logs/cache may persist sensitive bodies and endpoints, which can mislead operators about actual data-retention risk. In a tool that handles secrets and forwards prompts to third-party APIs, inaccurate security disclosures materially increase the chance of accidental exposure.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The header says environment keys override disk storage and implies they are a supported credential path. In practice, shouldAttachAuth reads allowlists only from keys[provider] on disk (L135-L152), and env-only providers have no mechanism to supply an allowlist, so auth attachment is refused and calls proceed unauthenticated or fail logically. This contradicts the documented security model and the --keys output that advertises env-only providers as supported.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The tool claims endpoint paths are not stored, but both cache and rate-limit state persist keys derived from provider plus path-only endpoints. Even without query strings, API paths frequently reveal sensitive business context such as model names, tenant-specific routes, internal API structure, or resource identifiers, so this is a documentation/behavior mismatch that can cause unintended metadata leakage to disk.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
67% confidence
Finding

The Agent Protocol uses imperative language such as Use the gateway and Add keys with allowlist as a general operating rule. While not a language/locale issue, this does not clearly violate the only policy example in scope, so confidence is limited; if interpreted as organizational natural-language policy, it is still weakly prescriptive rather than offering choice.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Low
Category
Not specified by scanner
Confidence
97% confidence
Finding

The top-level documentation advertises a retention-setting feature, but the only handling is parsing --retention into result.flags.retention at L738-L740. No later code uses that value to update TTLs, log retention, or persisted settings, so the documented behavior contradicts actual execution.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.