Back to skill

Security audit

Google Free Media Skill

Security checks for vulnerabilities and agentic risk

Overview

This appears to be an incomplete demo skill that encourages Google browser session reuse and can misleadingly report media generation success, so it should be reviewed before installation.

Install only if you are comfortable treating this as a demo scaffold, not a working media generator. Use a dedicated Google account if you implement the browser automation, avoid storing reusable Google session data unless it is protected and isolated, pin dependencies with a lockfile, and fix the shell command construction before running it from untrusted paths.

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 (2)

T08 · Insecure Dependencies

Warning
Location
README.md:7
Finding
Unpinned Third-Party Dependency Installation<![CDATA[ ## Vulnerability Details **File Location**: `README.md:7-8` and `SKILL.md:140` **Vulnerability Type**: Unpinned third-party dependency and mutable supply-chain resolution **Risk Level**: Medium ### Vulnerable Code `README.md:7-8`: ```bash cd /mnt/storage/ada_projects/google-free-media-skill npm install puppeteer ``` `SKILL.md:140`: ```text 1. Install Puppeteer: npm install puppeteer ``` ### Technical Analysis The installation instructions retrieve the latest version of Puppeteer without specifying an exact version. The project also does not include a reviewed `package.json` or committed lockfile that would constrain the package and its transitive dependencies to known versions and integrity hashes. Consequently, the effective dependency graph can change after the Skill has been audited. An unexpected, compromised, or malicious future package release could execute package lifecycle scripts or introduce unsafe runtime behavior with the privileges of the user performing the installation. This is a supply-chain weakness rather than evidence that the current Puppeteer package is malicious. ### Attack Path 1. A user follows the documented setup instructions. 2. `npm install puppeteer` queries the configured npm registry for the currently resolved release. 3. npm resolves a mutable package version and transitive dependency graph not reviewed as part of this project. 4. If the package, a transitive dependency, the registry configuration, or the relevant publisher account has been compromised, npm installs the attacker-controlled release. 5. Any permitted lifecycle script executes with the installing user's privileges, or malicious dependency code executes when subsequently imported. ### Impact Assessment Successful exploitation could execute arbitrary code under the account running npm or the Skill. This may permit access to files, environment variables, browser profiles, Google session material, and other resources available to that account. The ...[truncated 189 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Add a reviewed `package.json` that pins Puppeteer to an exact version rather than a range. 2. Generate and commit a lockfile containing the complete dependency graph and integrity hashes. 3. In deployment documentation, replace ad hoc installation with: ```bash npm ci ``` 4. Review package provenance, publisher history, lifecycle scripts, and transitive dependencies before updating the lockfile. 5. Use a trusted registry and enforce registry configuration so package names cannot resolve through an unintended source. 6. Consider `npm ci --ignore-scripts` where compatible. If lifecycle scripts are required, explicitly review and permit them. 7. Run dependency installation as a dedicated, unprivileged user without access to browser profiles or unrelated secrets. 8. Integrate dependency auditing and controlled update review into the release process. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/generate_image.mjs:94
Finding
Shell Command Injection Through Unquoted Project Path<![CDATA[ ## Vulnerability Details **File Location**: `scripts/generate_image.mjs:94`, `scripts/generate_image.mjs:174`, `scripts/generate_video.mjs:84`, and `scripts/generate_video.mjs:180` **Vulnerability Type**: Shell command injection through unsafe command construction **Risk Level**: Medium ### Vulnerable Code `scripts/generate_image.mjs:93-98`: ```js try { const quotaCheck = execSync(`node ${__dirname}/quota_manager.mjs check`, { encoding: 'utf-8' }); console.log(quotaCheck); } catch (e) { console.log('⚠️ ไม่สามารถตรวจสอบ quota ได้ (ดำเนินการต่อ)'); } ``` `scripts/generate_image.mjs:173-178`: ```js try { execSync(`node ${__dirname}/quota_manager.mjs consume image 1`, { stdio: 'ignore' }); } catch (e) { // Ignore quota errors } ``` `scripts/generate_video.mjs:83-88`: ```js try { const quotaCheck = execSync(`node ${__dirname}/quota_manager.mjs check`, { encoding: 'utf-8' }); console.log(quotaCheck); } catch (e) { console.log('⚠️ ไม่สามารถตรวจสอบ quota ได้ (ดำเนินการต่อ)'); } ``` `scripts/generate_video.mjs:179-184`: ```js try { execSync(`node ${__dirname}/quota_manager.mjs consume video 1`, { stdio: 'ignore' }); } catch (e) { // Ignore quota errors } ``` ### Technical Analysis `execSync()` receives a single command string and executes it through a shell. The scripts interpolate `__dirname` directly into that command without shell quoting or argument separation. Although `__dirname` is not supplied as a normal command-line argument, it is derived from the directory in which the project is installed. If an attacker can influence the extraction, checkout, mount, or installation path, shell metacharacters embedded in that path can terminate or modify the intended command and append an attacker-selected command. The issue is repeated in both generation scripts for quota checks and quota consumption. Error suppression around quota consumption does not mitigate command execution because the shell processes injected content before ...[truncated 1525 chars]
Remediation
<![CDATA[ ## Remediation Suggestions Avoid invoking a shell. Use `execFileSync()` or `spawnSync()` with the Node executable and each argument passed separately: ```js import { execFileSync } from 'child_process'; import { join } from 'path'; const quotaManagerPath = join(__dirname, 'quota_manager.mjs'); const quotaCheck = execFileSync( process.execPath, [quotaManagerPath, 'check'], { encoding: 'utf-8' } ); execFileSync( process.execPath, [quotaManagerPath, 'consume', 'image', '1'], { stdio: 'ignore' } ); ``` Apply the same pattern to the video quota command: ```js execFileSync( process.execPath, [quotaManagerPath, 'consume', 'video', '1'], { stdio: 'ignore' } ); ``` Additional hardening measures: 1. Use `process.execPath` instead of relying on a shell-resolved `node` executable. 2. Keep `shell` disabled and pass all command arguments as an array. 3. Resolve and validate the quota manager path before execution. 4. Do not attempt to fix this solely by adding manual quotes; shell-free process creation is more robust across platforms. 5. Add regression tests that execute the project from paths containing spaces and shell metacharacters. 6. Run the Skill under a least-privileged account with limited access to browser sessions and unrelated files. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Rogue AgentSelf-Modification, Session Persistence
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (15)

Self-Modification

High
Category
Rogue Agent
Content
1. **Quota ฟรีจำกัด**: Gemini ~100 รูป/วัน, Flow ~50 credits/วัน (อาจเปลี่ยนแปลง)
2. **ช้ากว่า API**: ต้องเปิด browser และรอ UI load (5-10x ช้ากว่า)
3. **เสี่ยง UI เปลี่ยน**: Google เปลี่ยนปุ่ม/ตำแหน่งบ่อย → อาจต้อง update skill
4. **Terms of Service**: Automation อาจขัดกับ ToS ของ Google free tier

## 📋 ขั้นตอนการทำงาน
Confidence
85% confidence
Finding
Skill modifies its own code, configuration, or behavior at runtime. Self-modification enables an agent to escalate privileges, disable safety constraints, or install persistent backdoors.

Natural-Language Policy Violations

Medium
Confidence
94% confidence
Finding
Natural-language guidance throughout the file is presented only in Thai, including setup, troubleshooting, and usage instructions. Under the language/locale policy, forcing a specific language without user opt-in or documented justification is a policy concern.

Missing User Warnings

Medium
Confidence
94% confidence
Finding
The skill explicitly recommends persisting login cookies/session storage for reuse in browser automation, but does not mention secure storage, scope restriction, expiration, or the privacy/credential risks if those artifacts are stolen. In this context, session tokens may grant direct access to the user's Google account and associated services without requiring a password, making compromise of the automation host materially dangerous.

Description-Behavior Mismatch

Medium
Confidence
98% confidence
Finding
The module header and manifest context present this skill as an operational free AI image generator using browser automation. However, the actual `generateWithGemini` function is explicitly a skeleton/demo and only saves placeholder metadata to a `.json` file while printing demo instructions, so the behavior materially differs from the claimed functionality.

Natural-Language Policy Violations

Medium
Confidence
92% confidence
Finding
The file description and operational messages are written in Thai, and the CLI help/output throughout the script is primarily Thai-facing. This imposes a specific language on users without any opt-in or alternative locale selection, which matches the language/locale policy violation criteria.

Description-Behavior Mismatch

Medium
Confidence
94% confidence
Finding
The success message implies completion of image generation and points to the requested output image path. In reality, the code writes only `outputPath.replace('.jpg', '.json')`, so users are told an image was produced when it was not, which is a direct description-behavior mismatch.

Natural-Language Policy Violations

Medium
Confidence
98% confidence
Finding
The file description and subsequent CLI messages are written in Thai, and the script does not provide any option to select another language or indicate that it is intentionally limited to Thai-speaking users. This creates a language/locale policy issue because the skill imposes a specific language by default without user opt-in.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Content
console.error('❌ ไม่พบ Chrome/Chromium ในระบบ');
    console.error('');
    console.error('ติดตั้งด้วยคำสั่ง:');
    console.error('  Ubuntu/Debian: sudo apt install chromium-browser');
    console.error('  macOS: brew install --cask google-chrome');
    return false;
  }
Confidence
70% confidence
Finding
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Content
console.error('❌ ไม่พบ Chrome/Chromium ในระบบ');
    console.error('');
    console.error('ติดตั้งด้วยคำสั่ง:');
    console.error('  Ubuntu/Debian: sudo apt install chromium-browser');
    console.error('  macOS: brew install --cask google-chrome');
    return false;
  }
Confidence
70% confidence
Finding
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Description-Behavior Mismatch

Medium
Confidence
98% confidence
Finding
The script advertises video generation and accepts an .mp4 output path, but in demo mode it only writes a JSON placeholder and never creates the promised video file. This can mislead downstream automation into treating the job as successful, causing integrity and workflow failures such as publishing missing assets or skipping error handling.

Intent-Code Divergence

Medium
Confidence
97% confidence
Finding
The completion message states success and prints the requested output path even though no video was generated there in demo mode. In an agent skill context, this is especially risky because other tools or users may rely on status text rather than artifact verification, leading to false success, broken pipelines, or accidental use of nonexistent media.

Natural-Language Policy Violations

Medium
Confidence
95% confidence
Finding
The code hard-codes the Thai locale and Bangkok timezone for date handling and uses Thai-only user-facing output throughout the script. This creates a natural-language/locale policy issue because the skill does not offer any user opt-in or configuration for language/locale selection, and no region-specific justification is provided in the file.

Missing User Warnings

Low
Confidence
82% confidence
Finding
This markdown file provides commands that generate image files to a specified output path, and later also shows analogous video generation commands. The guide gives no user-facing warning that running these commands will create files on disk and may overwrite existing files depending on script behavior, which is a data-affecting action relevant to markdown warning requirements.

Natural-Language Policy Violations

Low
Confidence
94% confidence
Finding
The manifest description forces a specific language for user-facing instructions, and the rest of the document is likewise Thai-centric. There is no opt-in, alternative language, or stated reason that the skill must be limited to Thai users.

Intent-Code Divergence

Low
Confidence
97% confidence
Finding
The inline comment at L054 states that Thai input will be converted to English first. The actual logic only detects Thai text and logs that it will be used as-is because Gemini supports Thai, which directly contradicts the comment.

Static analysis

Detected: suspicious.dangerous_exec

Shell command execution detected (child_process).

Critical
Code
suspicious.dangerous_exec
Location
scripts/generate_image.mjs:74

Shell command execution detected (child_process).

Critical
Code
suspicious.dangerous_exec
Location
scripts/generate_video.mjs:45