Back to skill

Security audit

google-search-web

Security checks for vulnerabilities and agentic risk

Overview

The skill is a straightforward web-search helper that sends queries and an optional service API key to a disclosed third-party endpoint, with no hidden persistence or destructive behavior.

Use this only if you trust coze-js-api.devtool.uk/devtool.uk with your search queries and any AZT API key. Avoid sensitive or confidential queries, and do not pass paid API keys directly on the command line; use an environment variable or managed secret instead.

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
scripts/google_search.py:92
Finding

API Key Accepted Through a Command-Line Argument

Content
View full analysis

Vulnerability Details

File Location: scripts/google_search.py:92 and SKILL.md:52-53
Vulnerability Type: Sensitive credential exposure through process arguments and shell history
Risk Level: Medium

The Skill explicitly supports supplying a paid API key through the --azt_api_key command-line argument.

Relevant documentation:

bash
# Paid version (pass directly as an argument)
python3 scripts/google_search.py --q "OpenAI news" --azt_api_key your_key_here

Relevant implementation:

python
parser.add_argument("--azt_api_key", default=None, help="API Key (may also be set through the AZT_API_KEY environment variable; optional for the free version)")

The argument is subsequently selected and transmitted to the configured third-party search endpoint:

python
def get_api_key(arg_key: str | None) -> str | None:
    """Prefer the key passed as an argument; otherwise read AZT_API_KEY."""
    return arg_key or os.environ.get("AZT_API_KEY", "").strip() or None


def google_search(q: str, azt_api_key: str | None = None) -> dict:
    payload: dict = {"q": q}
    if azt_api_key:
        payload["api_key"] = azt_api_key

    try:
        response = requests.post(
            API_URL,
            json=payload,
            timeout=150,
            headers={"Content-Type": "application/json"},
        )

Technical Analysis

Secrets supplied as command-line arguments may be retained in shell history and can be exposed in process listings or operating-system process metadata while the program is running. On systems where process arguments are visible to other users, containers, monitoring agents, diagnostic collectors, or CI logging systems, an observer may recover the API key without compromising the HTTPS connection.

The key is intentionally sent in the JSON body to https://coze-js-api.devtool.uk/google/search/web. Sending an authentication credential to the service that validates it is consistent with the declared search functional ...[truncated 1820 chars]

Remediation
View remediation

Remediation Suggestions

  1. Remove the --azt_api_key argument and its documented usage. Read the credential only from a protected secret source such as AZT_API_KEY, a secret manager, or an inherited file descriptor.

  2. If interactive entry is required, use getpass.getpass() so the key is not echoed or placed in shell history:

    python
    from getpass import getpass
    
    api_key = os.environ.get("AZT_API_KEY", "").strip() or getpass("API key: ").strip()
    
  3. For automation, configure the execution platform's secret-injection mechanism and ensure secret masking is enabled in logs.

  4. Avoid printing the key, request payload, or request headers in normal output, error handling, or future debug logging.

  5. Update SKILL.md to show only safe credential-loading examples and warn users not to place credentials in command-line arguments.

  6. Make the implementation and documentation agree on credential precedence. Prefer an approved secret source rather than allowing an exposed command-line value to override it.

  7. Document that both the search query and API key are transmitted to coze-js-api.devtool.uk, allowing users to make an informed trust decision before invoking the Skill.

  8. Rotate any API key that has previously been supplied through the documented command-line form or exposed in shell or CI logs.

Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • 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
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (6)

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
92% confidence
Finding

The skill invokes a Python script that uses network access and may read an API key from the environment, but the manifest does not declare any tool scope or permissions. This weakens policy enforcement and user/operator visibility, making it easier for the skill to access network and secrets implicitly without explicit approval boundaries.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The skill does not clearly warn users that their search query and optional API key will be transmitted to an external service. Without a prominent disclosure, users may provide sensitive queries or credentials without understanding the privacy and security implications of the network request.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The trigger conditions are broad enough to match many ordinary search-related requests, so the skill may be invoked in cases where the user did not intend an external API call. In this context, overbroad routing increases the chance of unnecessary data disclosure because user queries are sent to a third-party service.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The script sends user search queries and an optional API key to a third-party service endpoint, which creates a real data disclosure risk because potentially sensitive queries and credentials leave the local environment. In this skill context, external transmission is expected for a search API, but the absence of an explicit user-facing notice, trust boundary explanation, or consent mechanism makes this more dangerous than a normal transparent web-search client.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
88% confidence
Finding

This code performs an outbound HTTP request to an external service and includes user-supplied search text and possibly an API key in the JSON body. External transmission is inherent to search functionality, but in a security review this is still a true issue because the endpoint is third-party and the skill does not provide strong transparency, validation of data handling expectations, or safeguards around sensitive input.

Content

Scanner excerpt · scripts/google_search.py (reported line 33)May include surrounding context.

python
payload["api_key"] = azt_api_key  # 接口字段名保持 api_key

    try:
        response = requests.post(
            API_URL,
            json=payload,
            timeout=150,

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
93% confidence
Finding

User-facing documentation, help text, and runtime messages are written exclusively in Chinese, with no option to select another language. This is a language policy concern because the skill effectively imposes a locale on all users without opt-in or documented justification.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.