Back to skill

Security audit

File Writer

Security checks for vulnerabilities and agentic risk

Overview

The skill is intended to write only scratch-area text files, but its own instructions and backup script leave under-scoped ways to run shell commands or affect files outside that boundary.

Install only if you are comfortable with a skill that can guide file writes and shell commands. Before use, it should be revised to remove shell fallbacks, use structured filesystem APIs, enforce canonical scratch-root containment, reject symlink traversal, and constrain the backup script to validated relative paths.

Vulnerability Patterns
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • 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
SKILL.md:23
Finding

Shell Command Injection Through Unescaped Directory and File Commands

Content
View full analysis

Vulnerability Details

File Location: SKILL.md:23 and SKILL.md:28
Vulnerability Type: Shell command injection
Risk Level: High

Vulnerable code:

text
3. Create subdirs if needed: Extract parent from rel_path; call 'exec'("mkdir -p [base_dir]/[parent]") or message: "Please run `mkdir -p [full_parent]` and confirm."
text
7. If tools fail, fallback: Message requesting user runs `echo "[content]" > [full_path]` or `>>` for append.

Technical Analysis

The workflow interpolates user-controlled path components into a shell command passed to exec. Its validation only rejects absolute paths, parent traversal, and selected file extensions. It does not reject or safely encode shell metacharacters, quotes, command substitution expressions, newlines, or other shell syntax.

For example, a relative parent directory containing command separators or command substitution syntax could still satisfy the documented path checks. If inserted into the mkdir -p command and interpreted by a shell, the additional syntax would be executed rather than treated as a literal directory name.

The fallback command has a similar defect: untrusted file content is placed inside a double-quoted echo command. Quotes, command substitutions, and shell syntax in the supplied content may break the intended command boundary. Although this fallback is presented to the user rather than necessarily executed by the Agent, it still generates an unsafe command that could lead to code execution if followed.

Attack Path

  1. An attacker requests a write to a relative path whose parent contains shell syntax while retaining an allowed extension.
  2. The path passes the documented checks because it does not begin with /, contain ../, or use a prohibited extension.
  3. The workflow constructs mkdir -p [base_dir]/[parent] by direct string interpolation.
  4. The command is passed to a shell-backed exec implementation. 5 ...[truncated 834 chars]
Remediation
View remediation

Remediation Suggestions

  • Do not construct shell commands by concatenating user-controlled values.
  • Create directories through a dedicated filesystem API.
  • If a subprocess is unavoidable, pass arguments as an array with shell interpretation disabled, such as shell=false.
  • Apply strict path-component validation in addition to canonical containment checks.
  • Remove the echo fallback. Write content through a filesystem API that accepts content separately from the destination path.
  • If command generation is unavoidable, use a rigorously reviewed encoding mechanism and never embed untrusted content directly in shell source.
  • Reject control characters, newlines, shell metacharacters, and ambiguous path components as defense in depth.

T05 · Unauthorized Access and Privilege Escalation

Error
Location
SKILL.md:15
Finding

Scratch Directory Restriction Can Be Bypassed Through Symbolic Links

Content
View full analysis

Vulnerability Details

File Location: SKILL.md:15-16, SKILL.md:22, and references/safety.md:4
Vulnerability Type: Symlink traversal and insufficient path containment validation
Risk Level: High

Vulnerable code:

text
- Base directory: /home/alfred/.openclaw/workspace/scratch. All paths relative to this (e.g., "notes.txt" or "subdir/log.md").
- Sanitize: Reject if path contains '../', starts with '/', or has non-text extensions (allow only .txt, .md, .log, .json).
text
2. Sanitize: Validate rel_path (no escapes, safe extension). Compute full_path = base_dir + rel_path.
text
- Reject regex: ^/|\.\./ (absolutes/parents)

Technical Analysis

The path restriction is lexical: it rejects leading slashes and ../, then concatenates the accepted relative path with the scratch root. It does not resolve the canonical path, inspect existing path components for symbolic links, or enforce no-follow behavior when files are opened.

A path such as linked-directory/notes.txt passes these checks. If linked-directory is a symbolic link to a directory outside the scratch root, ordinary read and write operations follow it. The effective target can therefore reside outside the authorized directory even though the submitted path is relative and contains no parent traversal token.

The same problem can affect overwrite, append, existence checks, and backup creation. A race is also possible if a validated path component is replaced with a symlink between validation and use.

Attack Path

  1. A symbolic link exists or is created below /home/alfred/.openclaw/workspace/scratch, pointing to a directory outside that root.
  2. An attacker requests an operation on a path below that link, such as linked-directory/target.txt.
  3. The path passes validation because it is relative, contains no ../, and has an allowed extension.
  4. The Skill concatenates the scratch root and the supplied ...[truncated 715 chars]
Remediation
View remediation

Remediation Suggestions

  • Canonicalize the scratch root and the target’s existing parent before every filesystem operation.
  • Verify that the resolved target remains strictly beneath the canonical scratch root.
  • Reject symbolic links in every path component.
  • Prefer descriptor-relative filesystem operations with no-follow and beneath-root enforcement, such as openat2 with appropriate resolution flags where supported.
  • Open final files with no-follow semantics and validate the resulting descriptor rather than relying solely on a prior path check.
  • Avoid separate validation and use steps that introduce time-of-check/time-of-use races.
  • Apply the same containment rules to reads, writes, appends, directory creation, and backups.

T05 · Unauthorized Access and Privilege Escalation

Warning
Location
scripts/backup_file.sh:4
Finding

Backup Script Allows Unrestricted Filesystem Paths

Content
View full analysis

Vulnerability Details

File Location: scripts/backup_file.sh:4-8 and scripts/backup_file.sh:21-22
Vulnerability Type: Missing path authorization and symlink protection
Risk Level: Medium

Vulnerable code:

bash
FULL_PATH="$1"
BASE_DIR=$(dirname "$FULL_PATH")
FILENAME=$(basename "$FULL_PATH")
EXT="${FILENAME##*.}"
NAME="${FILENAME%.*}"
bash
cp "$FULL_PATH" "$BAK_PATH"
echo "Backed up to $BAK_PATH"

Technical Analysis

The bundled fallback script accepts its first argument as a complete path and immediately derives a destination in the same directory. It does not verify that the argument is relative to /home/alfred/.openclaw/workspace/scratch, canonicalize the path, reject parent traversal, or detect symbolic links.

Quoting protects these particular uses from ordinary shell word splitting, but it does not establish an authorization boundary. cp follows the source path and can also follow an existing destination symlink. The script therefore does not independently enforce the restrictions declared by the Skill.

Attack Path

  1. The fallback script is invoked with an absolute path, a path containing parent traversal, or a path that resolves through a symbolic link.
  2. The script accepts the argument without validating its relationship to the scratch root.
  3. It derives a backup filename in the source file’s directory.
  4. cp reads the supplied source and writes to the derived destination.
  5. The operation occurs outside the intended scratch directory if the process account has sufficient permission.

If an attacker can pre-create the selected destination as a symbolic link, the copy may also overwrite the link’s external target.

Impact Assessment

The script can copy and create or overwrite files beyond the intended scratch boundary under the invoking account’s privileges. This may expose copies of local files, alter files in unauthorized directories, or o ...[truncated 115 chars]

Remediation
View remediation

Remediation Suggestions

  • Require exactly one relative-path argument and reject empty or additional arguments.
  • Hard-code or securely configure the permitted scratch root inside the script.
  • Resolve the source and destination parents and verify that both remain beneath the canonical root.
  • Reject symbolic links in source and destination path components.
  • Use no-follow and exclusive-creation semantics for the backup destination.
  • Invoke utilities with an option terminator after validation, such as cp -- "$FULL_PATH" "$BAK_PATH".
  • Prefer implementing backup creation through a safe filesystem API rather than a standalone shell script.

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/backup_file.sh:10
Finding

Backup Selection Logic Overwrites Existing Primary Backups

Content
View full analysis

Vulnerability Details

File Location: scripts/backup_file.sh:10-21
Vulnerability Type: Incorrect backup existence check and non-atomic file creation
Risk Level: Medium

Vulnerable code:

bash
# Find next .bak.N
N=0
while [ -f "$BASE_DIR/$NAME.bak.$N.$EXT" ]; do
  N=$((N+1))
done

if [ $N -eq 0 ]; then
  BAK_PATH="$BASE_DIR/$NAME.bak.$EXT"
else
  BAK_PATH="$BASE_DIR/$NAME.bak.$N.$EXT"
fi

cp "$FULL_PATH" "$BAK_PATH"

Technical Analysis

The loop initially checks for NAME.bak.0.EXT, but when N remains zero the script writes to NAME.bak.EXT. It never checks whether that actual destination already exists. Consequently, an existing primary backup can be silently overwritten whenever NAME.bak.0.EXT is absent.

Destination selection and copying are also separate operations. Another process can create or replace the chosen destination after the check and before cp, creating a time-of-check/time-of-use race. Because ordinary cp does not create the destination exclusively and can follow a destination symlink, this race can cause unintended overwrite behavior.

Attack Path

  1. A legitimate backup such as document.bak.txt already exists.
  2. The file document.bak.0.txt does not exist.
  3. The script initializes N=0 and checks only for document.bak.0.txt.
  4. Because that file is absent, the loop does not run.
  5. The script selects document.bak.txt without checking it.
  6. cp overwrites the existing backup.

For a race-based attack, an attacker able to modify the destination directory can replace the selected destination with a symlink before the copy occurs, potentially redirecting the overwrite.

Impact Assessment

Existing backup history can be destroyed, defeating the documented recovery guarantee and causing loss of prior file versions. Where an attacker can manipulate the destination directory, the non-atomic operation may also permit overwrite of an ...[truncated 98 chars]

Remediation
View remediation

Remediation Suggestions

  • Check the exact filename that will subsequently be used.
  • Use one consistent sequence, for example file.bak.ext, file.bak.1.ext, and file.bak.2.ext.
  • Create the selected backup atomically with exclusive creation so an existing file cannot be replaced.
  • Reject symbolic-link destinations and use no-follow behavior.
  • Copy through an already validated file descriptor where possible to prevent path replacement races.
  • Fail safely if no unique destination can be created, and never overwrite an existing backup.
Vulnerability Patterns
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • 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
Findings (5)

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The skill claims to safely restrict writes to a scratch directory with path validation, backup handling, and text-only enforcement, but the documented workflow does not actually guarantee those controls and even references fallback behaviors that could operate on arbitrary paths. A description-behavior mismatch is dangerous because downstream agents or users may trust the safety claims and invoke the skill in sensitive contexts, leading to unauthorized file access or overwrite outside the intended sandbox.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The documentation states the skill is not for executing code, yet the workflow explicitly uses exec and recommends shell commands as fallback. This contradiction can mislead reviewers into underestimating the skill's capabilities while still enabling command execution paths that may be abused for filesystem access or command injection.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

Broad trigger phrases such as everyday requests to 'update the script' or 'write that information' increase the chance that the skill activates in contexts where the user did not intend a file operation. In a file-writing skill, unintended activation can lead to unauthorized persistence of sensitive text, accidental overwrites, or confusing cross-tool behavior.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

Using exec for directory creation and documenting shell-command fallbacks expands the attack surface beyond simple file-writing primitives. If rel_path or content handling is ever incomplete, shell-based mkdir or echo redirection can become a vehicle for command injection, argument confusion, or writes that bypass the intended safety controls.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The safety reference instructs the agent to run mkdir -p [path] or ask for confirmation to execute it, which conflicts with the skill's stated boundary that it is not for executing code. Even though mkdir is limited in scope, this expands the skill from file writing into command execution and could normalize shell invocation paths that are riskier if path validation fails or later logic is extended.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.