Back to skill

Security audit

Gemini Image Generation

Security checks for vulnerabilities and agentic risk

Overview

The skill is a coherent Gemini image tool, but it gives its scripts broader file read, upload, and overwrite authority than the documentation safely constrains.

Install only if you trust the skill operator and will keep invocations tightly scoped. Use workspace-local source images and output paths, avoid setting GEMINI_BASE_URL unless it is a trusted HTTPS endpoint, do not provide sensitive files as inputs, and consider adding a lockfile or pinning dependencies before production use.

Vulnerability Patterns
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • 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
Findings (4)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/gemini-image-runtime.mjs:127
Finding

Unrestricted Local File Read and Transmission to a Remote Service

Content
View full analysis
1 && mimeTypes.length !== inputPaths.length) { throw new Error("Pass either one --mime-type for all inputs or one --mime-type per --input"); } return Promise.all( inputPaths.map(async (inputPath, index) => { const imageBuffer = await fs.readFile(inputPath); const mimeType = mimeTypes[index] || mimeTypes[0] || mimeTypeForPath(inputPath); return { mimeType, data: imageBuffer.toString("base64"), }; }), ); } ``` The corresponding call site accepts the input path directly from command-line arguments: ```js const args = parseArgs(process.argv.slice(2)); const prompt = requireSingleArg(args.prompt, "prompt"); const inputs = normalizeArgList(requireSingleArg(args.input, "input")); const output = requireSingleArg(args.output, "output"); const mimeTypes = normalizeArgList(args["mime-type"]); const imageConfig = readImageConfigArgs(args); const inlineDataParts = await createInlineDataParts(inputs, mimeTypes); const { ai, model } = createGeminiImageClientFromEnv(); const response = await ai.models.generateContent( createImageGenerationRequest({ model, prompt, inlineDataParts, imageConfig, }), ); ``` ### Technical Analysis The `--input` argument is treated as a filesystem path and passed directly to `fs.readFile`. The implementation does not: - Restrict the path to an approved workspace or input directory. - Reject absolute paths or `..` traversal. - Resolve and validate the canonical path. - Detect symlinks that resolve outs ...[truncated 1590 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/gemini-image-runtime.mjs:159
Finding

Unrestricted Output Path Allows File Creation and Overwrite Outside the Workspace

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/gemini-image-runtime.mjs:106
Finding

Unvalidated Custom Base URL Can Expose API Credentials and User Content

Content
View full analysis
Remediation
View remediation

T08 · Insecure Dependencies

Note
Location
package.json:5
Finding

Unpinned Third-Party Dependency and Missing Lockfile Reduce Build Integrity

Content
View full analysis
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Rogue AgentSelf-Modification, Session Persistence
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (6)

Ae2

Medium
Category
analysis-evasion
Confidence
90% confidence
Finding

Artifact content does not match its filename extension

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
60% confidence
Finding

Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Content

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

md
# Image Generation

Use this skill when you need to create one or more image files from a text prompt, or edit one or more existing images with Gemini.

## Requirements

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
83% confidence
Finding

The function reads local image files, base64-encodes them, and prepares them as inline data for a request that is later sent through the GoogleGenAI client. This is a network transmission of user-provided file contents, but the file contains no prompt, log, or explanatory comment warning that local images may be sent to an external service.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
87% confidence
Finding

This code creates directories and writes model-returned image data to the filesystem, which is a safety-relevant file write operation. In this file there is no confirmation prompt, user-facing log/print, or explanatory comment/docstring disclosing that the operation will persist files to the specified path.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
93% confidence
Finding

The dependency is version-ranged with a caret (^1.44.0), which allows newer compatible releases to be installed over time. This can introduce supply-chain risk and reduce build reproducibility if a compromised or breaking upstream release is published, though the package file alone does not indicate active exploitation.

Content

Scanner excerpt · package.json (reported line 6)May include surrounding context.

json
"private": true,
  "type": "module",
  "dependencies": {
    "@google/genai": "^1.44.0"
  }
}

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
79% confidence
Finding

This function reads GEMINI_API_KEY from the environment, which is sensitive credential access. The file does not include any user-facing notice, comment, or documentation string explaining that the skill depends on and will consume a credential from environment variables.

Content

No source excerpt is available for this finding.