Back to skill

Security audit

French Learning

Security checks for vulnerabilities and agentic risk

Overview

The skill mostly matches its French-learning purpose, but it uses Google and AI service credentials to transmit content and clear, rewrite, or upload cloud data with weak safeguards.

Review this skill before installing. Use it only with a dedicated Google account or tightly scoped credentials, confirm the fixed Sheet and Drive IDs are yours or intentionally shared, and avoid running it on sensitive sheets until formula sanitization, temp-file handling, path validation, and confirmation or backup steps are added.

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

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/generate_audio.py:47
Finding

Path Traversal Through Untrusted Sheet Indices Can Overwrite or Delete Files

Content
View full analysis
Remediation
View remediation
1_000_000: raise ValueError("Index is outside the permitted range") return index ``` 2. Generate filenames exclusively from validated numeric values. 3. Create a private temporary directory with `tempfile.TemporaryDirectory()` rather than writing directly under the shared `/tmp` directory. 4. Resolve the final path and verify that it remains under the intended temporary directory: ```python from pathlib import Path output_dir = Path(temp_dir).resolve() output_path = (output_dir / f"{start_idx}-{end_idx}.mp3").resolve() if output_dir not in output_path.parents: raise ValueError("Invalid output path") ``` 5. Before deletion, verify that the path is a regular file created during the current execution and remains inside the private temporary directory. 6. Reject index values containing separators, traversal components, control characters, or non-numeric content. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/format_excel.py:82
Finding

Formula Injection When Untrusted Data Is Written Using USER_ENTERED Mode

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/fix_update.py:7
Finding

Predictable Shared Temporary File and TOCTOU Race Permit Sheet Data Substitution

Content
View full analysis
Remediation
View remediation
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
Findings (30)

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding

The skill description omits materially relevant behavior such as LLM-generated translations/examples and appears to overstate or misstate audio/upload capabilities. In a skill that handles educational content and cloud resources, inaccurate declarations undermine reviewability and can mask outbound data sharing or content generation that users did not expect.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

The skill description omits materially relevant behavior such as LLM-generated translations/examples and appears to overstate or misstate audio/upload capabilities. In a skill that handles educational content and cloud resources, inaccurate declarations undermine reviewability and can mask outbound data sharing or content generation that users did not expect.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

The skill description omits materially relevant behavior such as LLM-generated translations/examples and appears to overstate or misstate audio/upload capabilities. In a skill that handles educational content and cloud resources, inaccurate declarations undermine reviewability and can mask outbound data sharing or content generation that users did not expect.

Content

No source excerpt is available for this finding.

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
96% confidence
Finding

This is a tool-parameter abuse risk because the subprocess call delegates a dynamically constructed command to the shell, which then performs expansion and command substitution. That makes the boundary between trusted code and shell-interpreted input fragile, and in a file-processing automation skill it is more dangerous because attacker-influenced content or environment state may reach the command path indirectly.

Content

Scanner excerpt · scripts/fix_update.py (reported line 12)May include surrounding context.

python
# Use bash to pass the file content directly
cmd_update = f"gog sheets update {TARGET_SHEET_ID} '{TARGET_SHEET_NAME}!A1' --values-json \"$(cat /tmp/french_learning_output_data.json)\" --json --input=USER_ENTERED"
subprocess.run(cmd_update, shell=True)

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
83% confidence
Finding

The skill advertises operational behavior that implies file and shell-capable automation, but it does not declare any explicit tool scope or permission boundaries. That creates ambiguity about what the agent may access at runtime and weakens least-privilege guarantees, especially for a skill that processes files and interacts with external services.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

Trigger phrases like 'process french vocab' and 'generate audio' are broad enough that the skill could activate in benign conversations without clear user intent. For a skill that can read files and send data to third-party services, ambiguous activation increases the chance of accidental execution and unintended data transmission.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The workflow description states that content is sent to Gemini and ElevenLabs and uploaded to Drive, but it does not present these as user-facing warnings or obtain explicit consent for external transmission and file creation. This is risky because vocabulary data, example sentences, or associated metadata may be sent to third parties or stored remotely without users appreciating the privacy and retention implications.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The document labels the skill as a French learning skill and the configuration explicitly targets generated French audio content. This imposes a specific language/locale without any stated user opt-in, alternative language selection, or justification that the skill is intentionally region- or language-specific under policy exceptions.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
87% confidence
Finding

The script reads a local JSON file and transmits its contents to Google Sheets through a subprocess, with no apparent disclosure, minimization, or content validation. If the file contains unexpected sensitive data or attacker-controlled spreadsheet formulas, the skill could leak local information or propagate malicious content into the sheet.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The skill updates an external Google Sheet via an external CLI, which causes data to leave the local environment and modify a remote resource. In this skill context that behavior is expected, but doing it through a shell command and external tool increases attack surface, reduces validation, and can bypass safer API-level controls.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

This code performs a remote spreadsheet update without any visible confirmation, approval gate, or warning to the user. In an automation skill that handles learning data this may be expected behavior, but silent modification of an external document can still be abused or cause unintended data tampering if triggered unexpectedly.

Content

No source excerpt is available for this finding.

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
95% confidence
Finding

The code invokes a shell with shell=True to execute a command string, which is dangerous because shell parsing and command substitution are involved. Even though the sheet ID and sheet name are constants, the command explicitly embeds $(cat /tmp/french_learning_output_data.json), so any compromise of the file path, shell environment, or surrounding command construction can lead to unintended command execution or unsafe data handling.

Content

Scanner excerpt · scripts/fix_update.py (reported line 12)May include surrounding context.

python
# Use bash to pass the file content directly
cmd_update = f"gog sheets update {TARGET_SHEET_ID} '{TARGET_SHEET_NAME}!A1' --values-json \"$(cat /tmp/french_learning_output_data.json)\" --json --input=USER_ENTERED"
subprocess.run(cmd_update, shell=True)

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 · scripts/format_excel.py (reported line 20)May include surrounding context.

python
try:
        # 1. Read data from Source Google Sheet (fr and en columns)
        cmd_get = ["gog", "sheets", "get", SOURCE_SHEET_ID, "Sheet1!A2:B1000", "--json"]
        res = subprocess.run(cmd_get, capture_output=True, text=True, check=True)
        source_data = json.loads(res.stdout).get("values", [])

        if not source_data:

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The manifest frames the skill as formatting vocab to a Google Sheet, but the code also generates new translations and example sentences via an LLM. This hidden expansion of capability increases data handling and external processing beyond expected scope, which is dangerous because users may not realize their content is being transformed and transmitted for AI enrichment.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The code transmits spreadsheet contents to Gemini without any visible privacy notice, consent mechanism, or data classification checks. This is dangerous because vocabulary sheets can still contain personal, proprietary, or sensitive material, and users may not expect an external model provider to receive that content.

Content

No source excerpt is available for this finding.

Ssd 1

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

Untrusted spreadsheet entries are embedded directly into the LLM prompt, enabling semantic prompt injection. A malicious cell value could instruct the model to ignore formatting rules, emit manipulated JSON, or include harmful/spurious content, which then gets written into the target sheet and may corrupt downstream automation.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

Executing the external Gemini CLI is a meaningful capability expansion beyond simple spreadsheet formatting and audio generation. In skill ecosystems, undeclared external model invocation is risky because it can leak user data, produce unreviewed content, and bypass user expectations about what the automation is allowed to do.

Content

No source excerpt is available for this finding.

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
77% confidence
Finding

Although the subprocess usage avoids shell injection, this call sends prompt text containing untrusted spreadsheet content to an external LLM CLI. That creates a real data-exfiltration and indirect prompt-injection surface because attacker-controlled sheet entries can influence model output and may disclose sensitive spreadsheet contents to a third-party service.

Content

Scanner excerpt · scripts/format_excel.py (reported line 64)May include surrounding context.

python
try:
                # Use gemini -p for non-interactive headless mode
                res_gemini = subprocess.run(
                    ["gemini", "-p", main_prompt],
                    capture_output=True, text=True, check=True
                )

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The script clears and overwrites the destination sheet automatically with no confirmation, backup, or transactional safety. If triggered on the wrong spreadsheet, with malformed output, or after prompt-influenced generation errors, it can irreversibly destroy or corrupt user data.

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 · scripts/format_excel.py (reported line 111)May include surrounding context.

python
# 2. Clear target sheet
        print("Clearing target sheet...")
        subprocess.run(
            ["gog", "sheets", "clear", TARGET_SHEET_ID, f"{TARGET_SHEET_NAME}!A1:F1000"],
            capture_output=True, text=True, check=True
        )

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 · scripts/format_excel.py (reported line 123)May include surrounding context.

python
] + new_data

        print(f"Writing {len(output_data)} rows to target sheet...")
        subprocess.run(
            [
                "gog", "sheets", "update",
                TARGET_SHEET_ID, f"{TARGET_SHEET_NAME}!A1",

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 · scripts/generate_audio.py (reported line 17)May include surrounding context.

python
def get_sentences() -> list:
    cmd = ["gog", "sheets", "get", TARGET_SHEET_ID, f"{TARGET_SHEET_NAME}!A2:E1000", "--json"]
    try:
        res = subprocess.run(cmd, capture_output=True, text=True, check=True)
        data = json.loads(res.stdout).get("values", [])
        
        sentences = []

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The skill takes content from a Google Sheet and sends it to the ElevenLabs-backed audio generation tool, which is a third-party service, without any explicit consent, disclosure, or data-classification check in the workflow. If the sheet contains sensitive student data, internal material, or copyrighted content, this causes an unintended external data disclosure.

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 · scripts/generate_audio.py (reported line 70)May include surrounding context.

python
combined_text,
            ]

            res = subprocess.run(cmd_sag, capture_output=True, text=True, check=True)
            print(f"Audio generated at {output_path}")
            
            # 4. Upload to Google Drive

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 · scripts/generate_audio.py (reported line 76)May include surrounding context.

python
# 4. Upload to Google Drive
            print(f"Uploading {filename} to Google Drive...")
            cmd_upload = ["gog", "drive", "upload", output_path, "--parent", folder_id, "--json"]
            subprocess.run(cmd_upload, capture_output=True, text=True, check=True)
            
            print(f"Uploaded {filename} successfully.")

Static analysis

No suspicious patterns detected.