Back to skill

Security audit

Web Search API

Security checks for vulnerabilities and agentic risk

Overview

This is a coherent SearchAPI-based web search skill, with credential-handling and locale-default caveats users should understand before use.

Install only if you are comfortable using your own SearchAPI key. Set language and country defaults to your preferred locale, avoid sharing the tool directory after configuration, and consider removing the key from shell history or using a safer local secret-handling workflow if adapting the tool.

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
tools/websearchapi/websearchapi.js:37
Finding
SearchAPI Credential Exposed Through Command-Line Arguments, Plaintext Storage, and URL Query Parameters## Vulnerability Details **File Locations**: - `SKILL.md:28-31` - `tools/websearchapi/websearchapi.js:37-40` - `tools/websearchapi/websearchapi.js:78-85` - `tools/websearchapi/websearchapi.js:124-126` **Vulnerability Type**: Insecure credential handling **Risk Level**: Medium ### Vulnerable Code The documented configuration procedure places the API key directly in a command-line argument: ```bash # Copy tools/websearchapi to your project # Configure API Key (required) cd tools/websearchapi node websearchapi.js config set-key YOUR_API_KEY ``` The key is saved as part of an unencrypted JSON configuration file without explicitly restrictive file permissions: ```javascript function saveConfig(config) { fs.writeFileSync(CONFIG_FILE, JSON.stringify(config, null, 2)); console.log('✅ 配置已保存到:', CONFIG_FILE); } ``` The saved key is subsequently inserted into the request parameters: ```javascript const params = { q: query, num: options.num || config.num, hl: options.lang || config.lang, gl: options.gl || config.gl, engine: engine, api_key: config.apiKey }; ``` Those parameters, including the credential, are serialized into the request URL: ```javascript function executeSearch(params, timeout) { return new Promise((resolve, reject) => { const url = `${API_BASE}?${querystring.stringify(params)}`; ``` ### Technical Analysis The API credential is exposed through three related channels: 1. Supplying the key as `config set-key YOUR_API_KEY` can retain it in shell history. Depending on operating-system access controls, command-line arguments may also be visible to other local processes while the command runs. 2. `fs.writeFileSync` stores the complete credential in `config.json` as plaintext. No explicit `0600` mode is requested, so effective permissions depend on the process umask and any permissions already present on the file. 3. The key is included in the HT ...[truncated 2025 chars]
Remediation
## Remediation Suggestions 1. **Avoid command-line key submission** - Prefer a protected environment variable such as `SEARCHAPI_API_KEY`. - If persistent configuration is necessary, read the key from an interactive hidden prompt or standard input rather than a positional argument. - Update `SKILL.md` and `README.md` so examples do not encourage placing credentials in shell history. 2. **Protect persistent configuration** - Create the configuration file with owner-only permissions: ```javascript fs.writeFileSync( CONFIG_FILE, JSON.stringify(config, null, 2), { mode: 0o600 } ); fs.chmodSync(CONFIG_FILE, 0o600); ``` - Store secrets separately from non-sensitive defaults. - Add `config.json` to `.gitignore`, package exclusion rules, backup exclusions where appropriate, and deployment secret-scanning policies. - Consider using the operating system's credential store or a managed secret service instead of a plaintext file. 3. **Reduce credential exposure in requests** - If SearchAPI supports an authorization header, transmit the key in that header instead of the URL. - If the provider mandates a query parameter, ensure request URLs are never logged and redact `api_key` from errors, tracing, telemetry, and proxy logs. - Review SearchAPI's official authentication guidance before changing the request format. 4. **Handle existing exposure** - Rotate any key previously configured through this mechanism. - Remove affected shell-history entries and URL-bearing logs where operationally possible. - Audit API usage for unexpected requests and configure quota or billing alerts.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
Findings (4)

Natural-Language Policy Violations

Medium
Confidence
95% confidence
Finding
The options table documents `--lang` defaulting to `zh-CN` and `--gl` defaulting to `cn`, which imposes a specific language and country locale by default. This is a natural-language policy concern because the skill does not present this as an opt-in choice or justify the locale restriction as region-specific.

Natural-Language Policy Violations

Medium
Confidence
92% confidence
Finding
The documentation states default locale settings of `zh-CN` for language and `cn` for country, which imposes a specific locale by default. Under the policy, forcing a specific language or locale without explicit user choice is a natural-language policy violation unless clearly justified as region-specific.

Natural-Language Policy Violations

Medium
Confidence
95% confidence
Finding
The tool hard-codes `lang: 'zh-CN'` and `gl: 'cn'` as defaults, causing all searches to be localized to Chinese language and China geography unless the caller explicitly overrides them. In an agent context, this can silently bias search results, censorship boundaries, regional availability, and ranking, which may mislead downstream decisions or expose users to jurisdiction-specific filtering without informed consent.

Natural-Language Policy Violations

Low
Confidence
92% confidence
Finding
The description text is written entirely in Chinese ("Agent 专用搜索工具 - 基于 SearchAPI"), which imposes a specific language in user-facing metadata without offering any language choice or documenting a justified locale restriction. This matches the policy category for language or locale constraints in natural-language content.