Back to skill

Security audit

gemini-file

Security checks for vulnerabilities and agentic risk

Overview

This Gemini wrapper mostly matches its purpose, but it gives the agent under-scoped file-write and executable-selection authority that users should review before installing.

Install only if you are comfortable with a Gemini helper that can write files locally and run the local Gemini CLI. Treat custom output paths and --gemini-bin as administrative or developer-only options; avoid using them from ordinary prompts, and do not use this skill with sensitive prompts unless you are prepared for the generated content to be saved on disk. The publisher should confine writes to a skill-owned outputs directory and remove or restrict arbitrary executable selection before this would be low-risk.

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

Error
Location
gemini_file_runner.py:111
Finding

Arbitrary File Write Outside the Intended Output Directory

Content
View full analysis
str: """Generate an output filename, preferring a user-provided name.""" if config.output_file is not None and config.output_file.strip() != "": return config.output_file.strip() timestamp = datetime.now().strftime("%Y%m%d-%H%M%S") extension = "json" if config.output_format == "json" else "txt" return f"gemini-output-{timestamp}.{extension}" ``` ```python def save_output(content: str, config: RunConfig) -> Path: """Write the result to a file and return its absolute path.""" config.output_dir.mkdir(parents=True, exist_ok=True) file_name = infer_filename(config) output_path = (config.output_dir / file_name).resolve() output_path.write_text(content, encoding="utf-8") return output_path ``` ### Technical Analysis The value supplied through `--output-file` is accepted without validating that it is a simple filename or confirming that the resolved destination remains inside `config.output_dir`. A value containing parent-directory components, such as `../../target`, causes `Path.resolve()` to normalize the destination outside the intended output directory. An absolute path has an equivalent effect because joining a `Path` with an absolute second operand discards the original output directory. The subsequent `write_text()` operation creates or truncates the resolved destination without checking whether the file already exists. It can also follow a destination symlink. Consequently, a caller who controls the runner arguments can write Gemini-generated content to any location writable by the process account. ### Attack Path 1. An attacker controls or influences the arguments used to invoke the runner. 2. The attacker supplies an output path such as: `` ...[truncated 1112 chars]
Remediation
View remediation
Path: if Path(output_file).is_absolute(): raise ValueError("Absolute output paths are not allowed.") if Path(output_file).name != output_file: raise ValueError("Output file must be a simple filename.") base = output_dir.resolve() destination = (base / output_file).resolve() if not destination.is_relative_to(base): raise ValueError("Output path escapes the approved directory.") if destination.is_symlink(): raise ValueError("Symlink destinations are not allowed.") return destination ``` Where supported, use exclusive file creation and fail safely when the destination already exists. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
gemini_file_runner.py:54
Finding

Undocumented Arbitrary Executable Selection Through --gemini-bin

Content
View full analysis
list[str]: """Build the Gemini CLI command from the configuration.""" cmd: list[str] = [config.gemini_bin] if config.model is not None and config.model.strip() != "": cmd.extend(["--model", config.model.strip()]) if config.output_format == "json": cmd.extend(["--output-format", "json"]) cmd.append(config.prompt) return cmd ``` ```python result = subprocess.run( cmd, capture_output=True, text=True, check=False, ) ``` ### Technical Analysis The `--gemini-bin` option allows the caller to place an arbitrary executable name or absolute path at argument position zero. `subprocess.run()` then launches that executable with the privileges of the Skill process. The use of an argument list and the absence of `shell=True` prevent conventional shell-metacharacter injection through the prompt. However, this protection does not address direct executable substitution: the caller can select a program other than Gemini. The option is also omitted from the optional-argument list in `SKILL.md`, making this execution capability broader than the documented Gemini-wrapper behavior. ### Attack Path 1. An attacker controls or influences the command-line arguments used to invoke the wrapper. 2. The attacker identifies an executable available on the system or places an executable in a writable location. 3. The attacker invokes the runner with an argument such as: ```text --gemini-bin /attacker/controlled/program ``` 4. `build_command()` uses the supplied value as the executable. 5. `subprocess.run()` launches the selected program under ...[truncated 768 chars]
Remediation
View remediation
Vulnerability Patterns
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (10)

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

The declared description frames the skill as one-shot Q&A/summarization/generation, but the body also introduces a file-oriented wrapper that writes outputs to disk, returns absolute paths, and accepts custom output directories and filenames. This mismatch can mislead reviewers and orchestration systems about the real capability surface, making unsafe file operations more likely to be triggered in contexts that only expected text generation.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
88% confidence
Finding

The skill documents shell execution and file-writing behavior, but it does not declare any explicit tool scope such as allowed tools or permissions. That makes the effective capabilities broader and less transparent to the caller, increasing the risk that an agent can invoke shell and write files without clear policy gating or user awareness.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The natural-language descriptions and argument help text are primarily in Chinese, which imposes a specific language on users without any visible opt-in or explanation. Under the stated policy, forcing a specific language without user choice is a locale/language policy concern.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The documentation states that output is saved under the skill directory, but the implementation permits writing anywhere the caller specifies. This mismatch can mislead reviewers and integrators into granting broader trust or permissions than the code actually deserves, increasing the chance of unsafe deployment.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The --output-dir and --output-file parameters let the caller write model output to arbitrary resolved filesystem locations instead of a confined skill-owned directory. In an agent environment this can be abused to overwrite user files, drop content into sensitive paths, or stage data in locations outside the skill's intended scope.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The --gemini-bin parameter allows the caller to execute any local binary or absolute path, not just the intended Gemini CLI. In an agent context, this turns a content-generation helper into a general command-execution primitive, greatly expanding capability and enabling arbitrary program execution under the agent's privileges.

Content

No source excerpt is available for this finding.

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · gemini_file_runner.py (reported line 111)May include surrounding context.

python
def run_gemini(config: RunConfig) -> str:
    """执行 Gemini CLI 并返回标准输出内容。"""
    cmd = build_command(config)
    result = subprocess.run(
        cmd,
        capture_output=True,
        text=True,

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
90% confidence
Finding

The documentation normalizes automatic file output and absolute path return without warning the user that content will be written to local disk. In agent settings, undisclosed persistence can create privacy, data handling, and workspace safety issues, especially if prompts or generated content contain sensitive information.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
80% confidence
Finding

The example command instructs the model to produce a Chinese-language story, which embeds a language preference in the skill documentation without clarifying that language should follow user preference. This can be read as endorsing a fixed locale behavior rather than offering language choice.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
89% confidence
Finding

This code creates an output directory and writes model output to a file, which affects local user data. Although the module docstring states that output is saved to a file, there is no runtime confirmation prompt or explicit user-facing warning at the point of the file write.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.