Back to skill

Security audit

Story Writer

Security checks for vulnerabilities and agentic risk

Overview

The skill is a coherent story-writing helper, but its save command can overwrite Markdown files outside its intended story folder.

Review this skill before installing if you plan to use the save command. Avoid untrusted story names or names containing slashes or '..', and be aware that drafts, history, and character names are written under the local story-writer data directory. The package does not show network exfiltration or automatic persistence beyond local files, but the path traversal bug should be fixed before routine use.

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

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/script.sh:250
Finding

Path Traversal Allows File Overwrite Outside the Story Directory

Content
View full analysis
"$DATA_DIR/stories/$name.md" echo " Saved: $name" _log "save" "$name" } ``` ### Technical Analysis The `cmd_save` function directly incorporates the user-controlled `name` argument into a filesystem path. Although the variable is quoted, quoting only prevents shell word splitting and expansion; it does not prevent path traversal sequences such as `../`. The destination is constructed as: ```text $DATA_DIR/stories/.md ``` An attacker can supply enough parent-directory components to escape `$DATA_DIR/stories` and select another writable file ending in `.md`. The redirection operator truncates an existing destination before writing standard input, so this can overwrite data outside the intended story-storage directory. The automatically appended `.md` suffix limits direct targeting to paths whose resulting filename ends in `.md`. Nevertheless, documentation, application data, repository files, and other Markdown files writable by the invoking user remain exposed. The function also follows symbolic links, which can increase the overwrite scope if a malicious or compromised local process can place a symlink in the stories directory. ### Attack Path 1. Determine or infer the configured data directory. By default it is: ```text $HOME/.local/share/story-writer ``` 2. Choose a writable target ending in `.md`, such as a Markdown file in another project directory. 3. Calculate a relative traversal path from: ```text $DATA_DIR/stories ``` to the target, omitting the final `.md` because the function appends it automatically. 4. Invoke the save command with the traversal sequence: ```bash printf '%s\n' 'attacker-controlled replacement content' | bash scripts/ ...[truncated 1152 chars]
Remediation
View remediation
&2 return 1 } ``` 2. Reject absolute paths, path separators, `.` and `..` components, control characters, and empty names. 3. Construct and canonicalize the destination, then verify that it remains beneath the canonical stories directory: ```bash stories_dir="$(realpath "$DATA_DIR/stories")" destination="$stories_dir/$name.md" resolved_parent="$(realpath -m "$(dirname "$destination")")" [[ "$resolved_parent" == "$stories_dir" ]] || { echo "Destination escapes the stories directory" >&2 return 1 } ``` 4. Prevent unintended truncation by using non-clobbering creation when overwriting is not explicitly requested: ```bash set -o noclobber cat > "$destination" ``` 5. Defend against symbolic-link targets. Check that the destination is not a symlink and, where available, use a secure file-opening mechanism with `O_NOFOLLOW`. 6. Consider separating the display title from the filesystem identifier. Generate a safe internal filename rather than treating an arbitrary story title as a path component. ]]>
Vulnerability Patterns
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
Findings (4)

Tp4

High
Category
MCP Tool Poisoning
Confidence
85% confidence
Finding

The code is broadly aligned with the creative-writing domain: it supports story structure generation, character generation, plot ideation, and worldbuilding. However, several declared capabilities are missing from the actual implementation. There is no command for dialogue generation, no functionality for story continuation/续写, and no meaningful bilingual documentation or special AI-agent integration beyond some mixed-language comments/help text. While the primary purpose matches partially, the declared description overstates the implemented features enough to count as a description-behavior mismatch.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
92% confidence
Finding

The save command writes arbitrary stdin content to a local file under the application's data directory without any user-facing disclosure that content will be persisted. For a writing tool, users may paste drafts, personal notes, or sensitive story material assuming an ephemeral interaction, so silent persistence can create privacy and data-retention risk on shared or monitored systems.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
95% confidence
Finding

The script's user-facing comments, help output, and generated content are entirely in Chinese, which effectively forces a specific language/locale. There is no indication that users can opt into another language or that the language restriction is documented as a justified regional constraint.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
96% confidence
Finding

This markdown file presents all substantive guidance in Chinese, which may force a specific language on users without opt-in. The policy allows locale constraints when explicitly justified, but no such justification or language choice appears here.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.