Back to skill

Security audit

Tagout

Security checks for vulnerabilities and agentic risk

Overview

This skill is a local tagout log tool, but it has unsafe shell handling that can allow command execution through its config command and weak safeguards around safety-related records.

Review before installing. Use this only for low-risk local notes unless the config command is fixed, JSON/CSV serialization is made safe, and destructive/export operations are clearly confirmed. Do not treat its stored data as reliable safety compliance evidence in its current form.

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

Error
Location
scripts/script.sh:136
Finding

Arbitrary Command Execution Through Configuration Arguments

Content
View full analysis
)"; fi elif [ -z "$val" ]; then grep "^${key}=" "$cfg" 2>/dev/null | cut -d= -f2- || echo "(not set)" else if [ -f "$cfg" ] && grep -q "^${key}=" "$cfg" 2>/dev/null; then sed -i "s|^${key}=.*|${key}=${val}|" "$cfg" else echo "${key}=${val}" >> "$cfg" fi echo "Set: $key=$val" fi } ``` ### Technical Analysis The `key` and `val` arguments are embedded directly into a GNU sed substitution expression. They are not validated or escaped for use as regular-expression, replacement, delimiter, or sed-command content. An attacker can place a crafted key in the configuration file and then supply a value containing the `|` delimiter and GNU sed's `e` flag. The resulting sed expression can cause the substituted line to be passed to `/bin/sh` for execution. The same unescaped key is also used as a regular expression in `grep`, but the command-execution consequence in the sed update path is the primary security issue. ### Attack Path One concrete exploitation sequence is: 1. Add a configuration entry whose key begins with a shell command and then introduces a shell comment: ```bash scripts/script.sh config 'id #' seed ``` This creates: ```text id #=seed ``` 2. Update that key with a value that terminates the replacement section and adds GNU sed's execution flag: ```bash scripts/script.sh config 'id #' 'x|e' ``` 3. The script constr ...[truncated 962 chars]
Remediation
View remediation
&2 return 1 fi ``` 2. Do not generate sed programs using untrusted input. Rewrite the configuration through a securely created temporary file using fixed field-comparison logic, then atomically rename it. 3. If sed must be retained, rigorously escape regular-expression metacharacters in the key and replacement metacharacters and delimiters in both the key and value. This is less robust than avoiding dynamic sed expressions. 4. Store configuration in a structured format and use a parser or serializer that treats keys and values exclusively as data. 5. Add regression tests containing sed delimiters, backslashes, newlines, regular-expression metacharacters, and strings resembling sed flags. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/script.sh:11
Finding

Tagout Record Injection and JSONL Corruption

Content
View full analysis
> "$DATA_DIR/data.jsonl" } ``` The vulnerable function receives attacker-controlled entry content from: ```bash cmd_add() { local value="${1:?Usage: tagout add }" shift || true _save_entry "add" "$value $*" local count=$(wc -l < "$DATA_DIR/data.jsonl" 2>/dev/null || echo 0) echo "Added: $value (entry #$count)" } ``` ### Technical Analysis The script constructs JSON by inserting values directly into a format string without JSON encoding. Shell quoting prevents immediate shell expansion, but it does not make the resulting content valid JSON. User-controlled values can contain: - Double quotes that terminate the JSON string. - Backslashes that alter JSON interpretation. - Newlines that introduce additional JSONL records. - Control characters that make records invalid. - Crafted field text that causes the script's grep-based parser to display misleading values. Because JSONL treats each physical line as a separate record and the application counts lines with `wc -l`, an embedded newline can create forged records that are later listed, searched, removed, exported, and counted as legitimate data. ### Attack Path 1. Invoke the `add` command with an argument containing a newline and a crafted JSON object: ```bash scripts/script.sh add $'legitimate value\n{"ts":"2099-01-01 00:00:00","cmd":"add","val":"forged compliance record"}' ``` 2. `_save_entry` writes the input without JSON escaping. 3. The newline splits the output across multiple physical lines in `data.jsonl`. 4. The second line resembles an independently stored tagout entry. 5. Subseq ...[truncated 698 chars]
Remediation
View remediation
> "$DATA_DIR/data.jsonl" ``` 2. Parse stored records with a JSON parser rather than regular expressions and `cut`. 3. If multiline values are not required, reject carriage returns, newlines, null bytes, and other prohibited control characters before persistence. 4. Validate every existing JSONL line before treating it as an entry, particularly before listing or exporting records. 5. Consider atomic writes and restrictive file permissions to further protect the integrity and confidentiality of compliance records. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/script.sh:119
Finding

CSV Formula Injection and Malformed CSV Export

Content
View full analysis
"$out" while IFS= read -r line; do ts=$(echo "$line" | grep -o '"ts":"[^"]*' | cut -d'"' -f4) c2=$(echo "$line" | grep -o '"cmd":"[^"]*' | cut -d'"' -f4) vl=$(echo "$line" | grep -o '"val":"[^"]*' | cut -d'"' -f4) echo "$ts,$c2,$vl" >> "$out" done < "$DATA_DIR/data.jsonl" ;; ``` ### Technical Analysis The export implementation concatenates values with commas but does not implement CSV escaping. Fields containing commas, double quotes, carriage returns, or newlines can alter the exported row and column structure. Additionally, attacker-controlled values beginning with spreadsheet formula markers such as `=`, `+`, `-`, or `@` are written unchanged. Spreadsheet applications may interpret these fields as formulas when a user opens the exported file. The exact behavior and available formula capabilities depend on the spreadsheet software and its security settings. Nevertheless, exporting untrusted data as active formula content creates a dangerous trust-boundary transition. ### Attack Path 1. Add an entry whose value begins with a spreadsheet formula marker, for example: ```bash scripts/script.sh add '=1+1' ``` 2. Export the data: ```bash scripts/script.sh export csv ``` 3. The exported row contains the attacker-controlled value without CSV quoting or formula neutralization: ```csv timestamp,command,value 2026-09-14 12:00:00,add,=1+1 ``` 4. A user opens `tagout-export.csv` in a formula-capable spreadsheet application. 5. The spreadsheet may evaluate the field as a formula rather than display it as literal tagout text. More complex formulas may have greater impact depending on spreadsheet capabilities, platform behavi ...[truncated 733 chars]
Remediation
View remediation
Vulnerability Patterns
  • 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
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (5)

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

The code does not implement a specialized tagout safety compliance tracker in any meaningful domain-specific way. It simply records arbitrary user-provided strings as log entries in a local JSONL file and provides generic CRUD-style operations plus export, stats, and config management. While the export to JSON/CSV and a status command loosely align with parts of the description, the primary behavior is a generic local data logger rather than a tool for checking tagout compliance or processing structured tagout tasks. This is a material description-behavior mismatch.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The description says "Use when json tagout tasks, csv tagout tasks, checking tagout status," which is not a clear, bounded invocation rule and does not specify exact trigger phrases or when the skill should not be used. For a markdown file, this creates an overly broad and ambiguous activation condition that could lead to unintended invocation.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The skill documents destructive and data-moving operations like 'remove' and 'export' without any warning, confirmation, or explanation of side effects. In a safety-related context, users may assume read-only compliance checking, so undocumented mutation/deletion behavior can lead to accidental loss or unauthorized handling of operational records.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The remove command irreversibly deletes a line from the data file with sed -i, but there is no confirmation prompt and no prior warning in the help text that this action modifies stored user data. Although the command prints a message after deletion, that does not disclose the destructive behavior before it happens.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
82% confidence
Finding

The export command creates or overwrites tagout-export.<fmt> in the working directory using cp and shell redirection, but the help text does not warn users that running export will write a file locally. The success message appears only after the write has already occurred.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.