Back to skill

Security audit

Anysearch

Security checks for vulnerabilities and agentic risk

Overview

This appears to be a legitimate web search skill, but its broad activation rules and credential handling deserve review before installation.

Install only if you are comfortable sending search terms, identifiers, and URLs to AnySearch. Prefer anonymous mode or an environment variable for the API key, avoid the --api_key flag, keep the skill .env file restricted to ANYSEARCH_API_KEY only, and do not use this skill for secrets, private internal URLs, or sensitive regulated data without explicit approval.

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

Warning
Location
scripts/anysearch_cli.sh:38
Finding
API Key Exposure Through Process Command-Line Arguments<![CDATA[ ## Vulnerability Details **File Location**: `scripts/anysearch_cli.sh:38-54`, `scripts/anysearch_cli.sh:98`, `scripts/anysearch_cli.sh:159`, `scripts/anysearch_cli.sh:184`, `scripts/anysearch_cli.sh:209`, and `scripts/anysearch_cli.py:203` **Vulnerability Type**: Credential exposure through process arguments **Risk Level**: Medium ### Vulnerable Code ```bash _call_api() { local tool_name="$1" local arguments="$2" local auth_args=() if [[ -n "$API_KEY" ]]; then auth_args+=(-H "Authorization: Bearer $API_KEY") fi local payload payload=$(jq -n --arg name "$tool_name" --argjson args "$arguments" \ '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":$name,"arguments":$args}}') local response response=$(curl -s -X POST "$ENDPOINT" \ -H "Content-Type: application/json" \ "${auth_args[@]}" \ -d "$payload" \ --max-time 30 2>/dev/null) ``` The shell command handlers also accept the secret directly through a command-line option: ```bash --api_key) API_KEY="$2"; shift 2 ;; ``` The Python implementation exposes the same user-facing option: ```python parser.add_argument("--api_key", default=os.environ.get("ANYSEARCH_API_KEY", ""), help="API key (optional)") ``` ### Technical Analysis The Bash implementation constructs an `Authorization` header containing the AnySearch API key and passes that header to `curl` as a command-line argument. As a result, even a key originally loaded from a protected environment file is copied into the argument vector of the spawned `curl` process. Depending on operating-system settings, process arguments can be visible through process inspection utilities, process accounting, endpoint monitoring, diagnostic collection, crash reports, or command execution logs. The explicitly supported `--api_key` option introduces an additional exposure route because the secret may also be recorded in shell history and appears in the parent CLI process arguments. This network authent ...[truncated 1304 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Remove the `--api_key` option from both implementations to prevent secrets from being placed in shell history and parent-process arguments. 2. Accept credentials only through a protected environment variable, operating-system credential store, or dedicated secret manager. 3. In the Bash implementation, do not place the authorization header directly in `curl`'s argument vector. Prefer an in-process HTTP client or another mechanism that does not disclose the header through process metadata. 4. If a temporary curl configuration or header file must be used, create it with restrictive permissions such as mode `0600`, avoid predictable names, and delete it reliably with a `trap`. 5. Document that users should rotate any API key previously supplied through `--api_key`. 6. Ensure operational logging and error handling never print authorization headers or secret-bearing command lines. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/anysearch_cli.py:18
Finding
Overbroad Environment-File Loading Permits Process Environment Injection<![CDATA[ ## Vulnerability Details **File Location**: `scripts/anysearch_cli.py:18-34` and `scripts/anysearch_cli.sh:12-27` **Vulnerability Type**: Unrestricted environment-variable injection from local configuration files **Risk Level**: Medium ### Vulnerable Code ```python def _load_env(): script_dir = os.path.dirname(os.path.abspath(__file__)) for env_path in [os.path.join(script_dir, ".env"), os.path.join(script_dir, "..", ".env")]: if os.path.isfile(env_path): with open(env_path, "r", encoding="utf-8-sig") as f: for line in f: line = line.strip() if not line or line.startswith("#"): continue if "=" not in line: continue key, _, value = line.partition("=") key = key.strip().lstrip("\ufeff") value = value.strip().strip("\"'").strip() if key and value: os.environ[key] = value _load_env() ``` The Bash implementation has equivalent behavior: ```bash _load_env() { for env_path in "$SCRIPT_DIR/.env" "$SCRIPT_DIR/../.env"; do if [[ -f "$env_path" ]]; then while IFS= read -r line || [[ -n "$line" ]]; do line="${line%%#*}" line="$(echo "$line" | xargs 2>/dev/null || true)" [[ -z "$line" || "$line" != *=* ]] && continue local key="${line%%=*}" local val="${line#*=}" val="$(echo "$val" | sed 's/^[\"\x27]\|[\"\x27]$//g')" export "$key=$val" done < "$env_path" fi done } ``` ### Technical Analysis The Skill only requires one configuration value, `ANYSEARCH_API_KEY`, but both implementations accept every key-value assignment found in either `scripts/.env` or the parent `.env` and export those values into the process environment. This exceeds the minimum configuration privilege needed for the declared functionality. Environment variabl ...[truncated 2103 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Replace the generic environment loader with an explicit allowlist that accepts only `ANYSEARCH_API_KEY`. 2. Do not copy parsed entries into `os.environ` or globally export them. Return the permitted key as a local value used only when constructing the request. 3. Reject malformed entries and ignore every unrecognized variable name. 4. Check that `.env` is a regular file, is not an unsafe symbolic link, is owned by the expected user, and is not writable by group or other users. 5. Prefer a single documented credential location rather than automatically searching both the script directory and its parent. 6. Recommend restrictive file permissions, such as mode `0600`, and avoid storing unrelated configuration in the credential file. 7. In Bash, avoid exporting the credential unless a child process specifically requires it; retain it in a shell-local variable wherever possible. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (15)

Credential Access

High
Category
Privilege Escalation
Content
- name: ANYSEARCH_API_KEY
    required: false
    description: "API key for higher rate limits. Anonymous access available with lower rate limits."
    storage: ".env file, environment variable, or --api_key CLI flag"
---

## Overview
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
fi

_load_env() {
  for env_path in "$SCRIPT_DIR/.env" "$SCRIPT_DIR/../.env"; do
    if [[ -f "$env_path" ]]; then
      while IFS= read -r line || [[ -n "$line" ]]; do
        line="${line%%#*}"
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
fi

_load_env() {
  for env_path in "$SCRIPT_DIR/.env" "$SCRIPT_DIR/../.env"; do
    if [[ -f "$env_path" ]]; then
      while IFS= read -r line || [[ -n "$line" ]]; do
        line="${line%%#*}"
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Lp3

Medium
Category
MCP Least Privilege
Confidence
94% confidence
Finding
The skill advertises and instructs use of shell, file reads, environment variables, and network access, but does not declare an explicit tool scope or permissions boundary. That makes the skill easier to invoke with broader-than-necessary capabilities and reduces the host's ability to enforce least privilege or warn users about what resources may be touched.

Missing User Warnings

Medium
Confidence
96% confidence
Finding
The skill description says it is a real-time search service but does not clearly disclose that user queries and requested URLs may be transmitted to an external provider. This creates a privacy and data-handling risk because users and orchestrators may not realize potentially sensitive prompts, identifiers, or internal URLs are leaving the local environment.

Vague Triggers

Medium
Confidence
92% confidence
Finding
The trigger conditions are very broad, covering generic information retrieval, fact-checking, web browsing, and multi-intent queries. In practice this can cause the skill to activate for many ordinary prompts, increasing unnecessary external requests and the chance that user data or browsing targets are sent to a third-party service without a clear need.

External Transmission

Medium
Category
Data Exfiltration
Content
"params": {"name": tool_name, "arguments": arguments},
    }
    try:
        resp = requests.post(ENDPOINT, json=payload, headers=_build_headers(api_key), timeout=30)
        resp.raise_for_status()
    except requests.exceptions.HTTPError as e:
        print(f"HTTP Error: {e}", file=sys.stderr)
Confidence
80% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Natural-Language Policy Violations

Medium
Confidence
98% confidence
Finding
The script unconditionally exports LANG and LC_ALL to en_US.UTF-8, which imposes a specific language/locale setting on every execution. This is a natural-language policy concern because it removes user locale choice and no opt-in or justification is provided in the file.

External Transmission

Medium
Category
Data Exfiltration
Content
export LANG=en_US.UTF-8
export LC_ALL=en_US.UTF-8

ENDPOINT="https://api.anysearch.com/mcp"
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"

if ! command -v jq &>/dev/null; then
Confidence
60% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
export LANG=en_US.UTF-8
export LC_ALL=en_US.UTF-8

ENDPOINT="https://api.anysearch.com/mcp"
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"

if ! command -v jq &>/dev/null; then
Confidence
60% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
export LANG=en_US.UTF-8
export LC_ALL=en_US.UTF-8

ENDPOINT="https://api.anysearch.com/mcp"
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"

if ! command -v jq &>/dev/null; then
Confidence
60% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
export LANG=en_US.UTF-8
export LC_ALL=en_US.UTF-8

ENDPOINT="https://api.anysearch.com/mcp"
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"

if ! command -v jq &>/dev/null; then
Confidence
60% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
'{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":$name,"arguments":$args}}')

  local response
  response=$(curl -s -X POST "$ENDPOINT" \
    -H "Content-Type: application/json" \
    "${auth_args[@]}" \
    -d "$payload" \
Confidence
70% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Missing User Warnings

Medium
Confidence
91% confidence
Finding
The specification explicitly supports fetching arbitrary user-supplied URLs and returning full page content, but it does not document safety boundaries, privacy implications, or restrictions on sensitive/internal targets. In an agent context, this can enable unintended outbound requests, retrieval of sensitive content, or SSRF-style abuse if the implementation does not strictly constrain reachable destinations.

Natural-Language Policy Violations

Low
Confidence
86% confidence
Finding
The specification includes a Chinese-only `query_format` example and multiple Chinese-language search examples, which can steer the skill toward a specific language/locale. The document does not state that this is optional, user-selected, or required for a region-specific mode, so it appears to impose a locale preference without opt-in.

Static analysis

No suspicious patterns detected.