Back to skill

Security audit

Gemini Deep Research (J-Claw)

Security checks for vulnerabilities and agentic risk

Overview

The skill can perform Gemini deep research, but it also adds under-disclosed credential handling, a detached background process, mutable third-party code, and automatic NotebookLM chaining that users should review before installing.

Install only if you are comfortable with a paid Gemini workflow that writes local task files and reports, runs a detached background poller, uses a mutable third-party extension, and may automatically hand the finished report to NotebookLM through another agent. Sensitive or proprietary research topics should not be used unless these behaviors are removed or separately confirmed at runtime.

Vulnerability Patterns
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
  • 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
Findings (4)

T01 · Skill Instruction Hijacking

Error
Location
SKILL.md:146
Finding

Automatic Invocation of an Unrequested Downstream Agent Workflow

Content
View full analysis
/dev/null || { log "WARNING: agent trigger failed, falling back to direct message" notify_user "$message" } } ``` ```bash # Trigger agent to chain the next workflow step (e.g., NotebookLM) # Pass all parameters the downstream skill needs TOPIC=$(python3 -c "import json; print(json.load(open('task.json'))['input'])" 2>/dev/null || echo "Deep Research") trigger_agent "✅ Deep Research 完成。请启动 NotebookLM 工作流,参数如下: - 报告路径:$OUTPUT_PATH - Notebook 名称:$TOPIC - 产出类型:Audio Overview (播客) - 格式:deep_dive - 长度:default - 语言:zh-CN 请创建 notebook、上传报告、生成播客。" ``` ### Technical Analysis The declared purpose of the Skill is to perform Gemini Deep Research, poll for completion, and save the resulting report. Once that work is complete, the generated polling script automatically invokes `openclaw agent` and instructs a new agent execution to create a NotebookLM notebook, upload the report, and generate an audio overview. This downstream operation is not necessary to complete the research task and is not separately presented for user confirmation. The instruction changes the effective goal of the workflow from “research and save a report” to “upload the report to another service and create additional content.” The fallback to a direct notification reduces availability impact if the agent call fails, but it does not prevent the initial unauthorized invocation. ### Attack Path 1. A user requests Gemini Deep Research and approves the research parameters. 2. The Skill writes and launches the detached `poll.sh` process. 3. The research provider returns a completed result. 4. ...[truncated 1111 chars]
Remediation
View remediation

T08 · Insecure Dependencies

Error
Location
references/setup-guide.md:27
Finding

Mutable Third-Party Extension Installed with Automatic Updates

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/dr-client.js:103
Finding

Overbroad Reading and Forwarding of Credential Environment Data

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
SKILL.md:184
Finding

Generated Polling Script Embeds Untrusted Task Values into Shell and Python Code

Content
View full analysis
/dev/null | grep -v "MCP server running" | tail -1 } ``` ```bash echo "$RESULT" | python3 -c " import sys, json d = json.loads(sys.stdin.read()) text = d['result']['content'][0]['text'] obj = json.loads(text) report = obj.get('outputs', [{}])[0].get('text', '') if report: with open('$OUTPUT_PATH', 'w') as f: f.write(report) print(f'Saved: {len(report)} chars') else: print('No report found') " >> poll.log 2>&1 ``` ### Technical Analysis Values read from `task.json`, including `researchId` and `outputPath`, are interpolated into executable shell, JSON, and Python source contexts without context-appropriate escaping. The most direct injection point is: ```python with open('$OUTPUT_PATH', 'w') as f: f.write(report) ``` A path containing a single quote and valid Python syntax can terminate the string literal and alter the generated Python program. The value is not passed as data through an argument or environment variable; it becomes part of source code interpreted by `python3 -c`. Similarly, `RESEARCH_ID` is embedded into a hand-constructed JSON string. Quotes, backslashes, newlines, or shell-sensitive content can corrupt the JSON-RPC message. Although normal research IDs are expected to follow a restricted provider-generated format, the script trusts the local `task.json` file and does not va ...[truncated 1939 chars]
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Rogue AgentSelf-Modification, Session Persistence
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
Findings (15)

Agent Config Directory Access

High
Category
Agent Snooping
Confidence
99% confidence
Finding

The fallback path reads from ~/.gemini/extensions/gemini-deep-research/.env to extract an API key from the agent's config directory. Accessing credential material directly from a config store is sensitive because it expands the skill from research orchestration into secret retrieval, and any compromise or misuse of subsequent shell steps can expose that credential.

Content

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

如果方法 A 失败,使用 方法 B(Shell Pipe 直连 MCP),这是经过验证可用的方式:

bash
export GEMINI_DEEP_RESEARCH_API_KEY=$(cat ~/.gemini/extensions/gemini-deep-research/.env | grep API_KEY | cut -d= -f2)
TASK_DIR="/tmp/gemini-deep-research/<task-dir>"
TOPIC=$(python3 -c "import json; print(json.load(open('$TASK_DIR/task.json'))['input'])")

Credential Access

High
Category
Privilege Escalation
Confidence
99% confidence
Finding

The skill explicitly accesses a .env file to extract an API key, which is direct credential handling in plaintext. This is dangerous because .env parsing via shell can leak secrets into process environments, logs, crash dumps, or child processes, and normalizes a pattern that makes secret exfiltration easier.

Content

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

如果方法 A 失败,使用 方法 B(Shell Pipe 直连 MCP),这是经过验证可用的方式:

bash
export GEMINI_DEEP_RESEARCH_API_KEY=$(cat ~/.gemini/extensions/gemini-deep-research/.env | grep API_KEY | cut -d= -f2)
TASK_DIR="/tmp/gemini-deep-research/<task-dir>"
TOPIC=$(python3 -c "import json; print(json.load(open('$TASK_DIR/task.json'))['input'])")

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
97% confidence
Finding

The background script goes beyond research orchestration by sending direct Discord messages and invoking another agent autonomously. This creates an unexpected cross-channel and cross-agent execution path that can act on user-derived data outside the original approval boundary, enabling unintended actions, spam, or data propagation.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The skill is presented as a deep-research/report-saving workflow, but it also auto-launches a NotebookLM workflow after completion. That hidden secondary behavior expands the skill's operational scope and can transmit report contents, paths, and metadata to another service without a fresh user decision.

Content

No source excerpt is available for this finding.

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · scripts/dr-client.js (reported line 103)May include surrounding context.

js
});
}

// ─── Load .env for MCP server ───────────────────────────────────────────────

function loadEnv(envPath) {
  const env = {};

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · scripts/dr-client.js (reported line 122)May include surrounding context.

js
return env;
}

const envPath = join(EXT_PATH, '.env');
const extEnv = loadEnv(envPath);

// ─── Spawn MCP Server ─────────────────────────────────────────────────────────

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
89% confidence
Finding

The skill performs code-capable actions including environment-variable access and shell execution, but does not declare a tool scope or allowed-tools boundary. That mismatch increases the chance that the runtime grants broader capabilities than users or reviewers expect, making later credential reads and autonomous actions less visible and less governed.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The trigger phrases are broad enough to match ordinary requests for research, increasing the chance this skill activates when the user did not intend to use Gemini CLI or external services. In security terms, over-broad invocation raises the probability of accidental data transmission, file writes, and autonomous background execution.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The description omits a clear warning that user prompts, metadata, and resulting reports are sent to external services and stored locally in temp/log/output files. Without that disclosure, users cannot make an informed consent decision about sensitive topics, proprietary data, or regulated content.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
83% confidence
Finding

The workflow persists task state in a temp directory across sessions, including topic, output path, and later a research ID. Persistence is not inherently malicious, but in this context it increases privacy and integrity risk because sensitive research topics and execution metadata remain on disk outside the interactive session lifecycle.

Content

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

md
| `poll-research.js` | Polls `research_status` every 5 min until done/timeout |
| `save-report.js` | Calls `research_save_report` once status is `completed` |

All scripts read/write `task.json` in the task's temp directory.

---

Ssd 3

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The skill automatically passes user-derived topic and report path into another agent workflow, creating implicit data flow across agents. Even if the values are not shell-evaluated here, this is still dangerous because it propagates potentially sensitive content and context into a separate execution environment without a new trust decision.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The downstream workflow hard-codes zh-CN as the output language without obtaining user approval. This can change the semantics and audience suitability of generated content and is especially risky because it happens in an automatic chained workflow rather than an interactive step.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
88% confidence
Finding

The documented 'Launch Background Process' step formalizes a persistent workflow that survives the current interaction. In combination with direct notifications and agent chaining, this persistence materially increases the blast radius of mistakes or abuse because actions can occur later and outside the original conversational context.

Content

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

done

text

### Step 5 — Launch Background Process

```bash
cd /tmp/gemini-deep-research/<task-dir>/

Session Persistence

Medium
Category
Rogue Agent
Confidence
90% confidence
Finding

Using nohup to launch a detached background poller creates an execution path that continues after the initiating session ends. Detached persistence is risky here because the process can keep sending messages, polling external services, writing files, and triggering agents without contemporaneous user oversight.

Content

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

bash
cd /tmp/gemini-deep-research/<task-dir>/
nohup bash poll.sh > /dev/null 2>&1 &
echo "Background PID: $!"

Ssd 3

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The documentation instructs storing complete MCP responses in poll.log, which may include sensitive research prompts, intermediate outputs, report text, identifiers, and service metadata in plaintext. Plaintext logging of full responses increases exposure through local access, backups, support bundles, and accidental sharing.

Content

No source excerpt is available for this finding.

Static analysis

Detected: suspicious.dangerous_exec

Shell command execution detected (child_process).

Critical
Code
suspicious.dangerous_exec
Location
scripts/dr-client.js:131

Shell command execution detected (child_process).

Critical
Code
suspicious.dangerous_exec
Location
scripts/poll-research.js:32

Shell command execution detected (child_process).

Critical
Code
suspicious.dangerous_exec
Location
scripts/save-report.js:22

Shell command execution detected (child_process).

Critical
Code
suspicious.dangerous_exec
Location
scripts/start-research.js:21