Back to skill

Security audit

Gemini Deep Research 1.0.0

Security checks for vulnerabilities and agentic risk

Overview

This is a straightforward Gemini Deep Research helper that uses the documented Google API and saves local reports, but users should avoid sending sensitive material unless approved.

Install only if you are comfortable sending research prompts and any referenced file-search context to Google Gemini. Prefer GEMINI_API_KEY over --api-key, avoid secrets or regulated data in queries, choose an output directory outside shared repositories when needed, and review or delete the generated JSON metadata after use.

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/deep_research.py:118
Finding
Gemini API Key Exposed Through Command-Line Arguments<![CDATA[ ## Vulnerability Details **File Location**: `scripts/deep_research.py`, lines 118-123 **Vulnerability Type**: Sensitive credential exposure through process arguments **Risk Level**: Medium ### Vulnerable Code ```python parser.add_argument("--api-key", help="Gemini API key (overrides GEMINI_API_KEY env var)") args = parser.parse_args() # Get API key api_key = args.api_key or os.environ.get("GEMINI_API_KEY") ``` ### Technical Analysis The script permits users to provide a Gemini API key through the `--api-key` command-line option. Command-line arguments are not an appropriate secret-transport mechanism because they may be: - Retained in shell history. - Captured by process monitoring or observability systems. - Visible through process inspection facilities to other authorized local users. - Included in diagnostic reports, terminal transcripts, or automation logs. Environment-based authentication is already supported, so accepting the same credential through a process argument unnecessarily increases its exposure. The script does not intentionally print or persist the key, and no evidence of transmission to an undeclared endpoint was found; the key is sent only to the documented Google Gemini API in the `x-goog-api-key` header. ### Attack Path 1. A user invokes the script with a command such as: ```bash scripts/deep_research.py --query "Research topic" --api-key "SECRET" ``` 2. The command and API key are retained in shell history, captured in logs, or exposed through local process inspection. 3. A local user or monitoring component with access to that information retrieves the key. 4. The exposed key is reused against Gemini API services within the permissions and quota associated with that credential. ### Impact Assessment Successful exploitation can disclose the Gemini API key. An attacker could use the credential to consume the associated API quota, incur costs, or access API resources authorized for that key. This issue does no ...[truncated 150 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Remove the `--api-key` command-line option. - Prefer the existing `GEMINI_API_KEY` environment variable or an operating-system credential manager. - If interactive entry is required, use `getpass.getpass()` so the credential is not echoed or placed in shell history. - For automation, support a permission-restricted credential file and validate that its permissions prevent access by unauthorized users. - Ensure application, shell, and CI/CD logs never include the credential. - Rotate any API key that has previously been supplied through the command line. ]]>

T09 · Insecure Skill Coding Practices

Note
Location
scripts/deep_research.py:43
Finding
Gemini API Requests Can Block Indefinitely Due to Missing Timeouts<![CDATA[ ## Vulnerability Details **File Locations**: `scripts/deep_research.py`, lines 43-47 and 65-68 **Vulnerability Type**: Unbounded network operations and polling **Risk Level**: Low ### Vulnerable Code ```python response = requests.post( f"{API_BASE}/interactions", headers=headers, json=payload ) ``` ```python response = requests.get( f"{API_BASE}/interactions/{interaction_id}", headers=headers ) ``` The polling loop is also unbounded: ```python while True: response = requests.get( f"{API_BASE}/interactions/{interaction_id}", headers=headers ) # ... time.sleep(10) # Poll every 10 seconds ``` ### Technical Analysis Neither the initial POST request nor subsequent GET requests define connection or read timeouts. The `requests` library can therefore wait indefinitely when the remote service, intermediary, or network connection stalls without closing. In addition, the polling loop has no overall deadline or maximum attempt count. Even if individual requests complete, a remote interaction that never transitions to `completed` or `failed` can keep the process running indefinitely. The destination is the documented Google Gemini endpoint, and the network behavior is necessary for the Skill's declared research functionality. The flaw is the absence of availability safeguards rather than unauthorized network access or data exfiltration. ### Attack Path 1. The script initiates a research interaction or polls an existing interaction. 2. The endpoint, a network intermediary, or a degraded connection accepts the request but does not complete the response, or the interaction remains perpetually pending. 3. Because no request timeout, polling deadline, or attempt limit is configured, the script remains blocked or continues polling. 4. The worker, terminal session, or Agent task remains occupied until it is manually terminated or externally killed. ### Impact Assessment The primary impact is loss of av ...[truncated 255 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Configure explicit connection and read timeouts for every request, for example: ```python timeout = (10, 60) requests.post(url, headers=headers, json=payload, timeout=timeout) requests.get(url, headers=headers, timeout=timeout) ``` - Catch `requests.Timeout` and `requests.RequestException` and return a controlled error. - Add bounded retries with exponential backoff and jitter for transient failures. - Enforce a maximum polling duration or maximum number of attempts. - Allow operators to configure the deadline while retaining a safe finite default. - Use a `requests.Session` with a retry-enabled adapter if consistent retry behavior is needed across all calls. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Taint TrackingDirect Taint Flow, Variable-Mediated Taint Flow, Credential Exfiltration Chain
  • 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 (5)

Tainted flow: 'interaction_id' from os.environ.get (line 139, credential/environment) → requests.get (network output)

Critical
Category
Data Flow
Content
}
    
    while True:
        response = requests.get(
            f"{API_BASE}/interactions/{interaction_id}",
            headers=headers
        )
Confidence
90% confidence
Finding
Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Lp3

Medium
Category
MCP Least Privilege
Confidence
93% confidence
Finding
The skill advertises capabilities that involve environment-variable access, network access, and file writing, but it does not declare an explicit tool scope such as permissions or allowed-tools. This creates a trust and governance gap: callers cannot easily constrain or review what resources the skill is expected to use, increasing the chance of over-broad execution in environments where such declarations are relied upon for policy enforcement.

Missing User Warnings

Medium
Confidence
96% confidence
Finding
The skill instructs users to send queries to an external Gemini API endpoint and optionally compare against a file-search store, but it does not clearly warn that user prompts and referenced data may be transmitted to third-party services. In a research skill, users are especially likely to submit internal strategy, market, or financial material, so the lack of an explicit privacy notice raises meaningful risk of unintended data exposure.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The documentation states that final reports and full interaction metadata are saved to timestamped files, but it does not warn that those files may contain sensitive prompts, research targets, internal context, or externally retrieved data. Persisting such material without an explicit privacy warning or retention guidance can lead to accidental local disclosure, inclusion in backups, or later exfiltration from the workstation or repository.

External Transmission

Medium
Category
Data Exfiltration
Content
"file_search_store_names": [file_search_store]
        }]
    
    response = requests.post(
        f"{API_BASE}/interactions",
        headers=headers,
        json=payload
Confidence
82% confidence
Finding
The script transmits user-supplied research queries, optional formatting instructions, and potentially file_search_store references to an external Google API. In this skill context, that behavior is expected, but it can still expose sensitive prompts, internal data references, or confidential research topics to a third party if users pass secrets or proprietary material.

Static analysis

No suspicious patterns detected.