Back to skill

Security audit

Task Interrupt Pro

Security checks for vulnerabilities and agentic risk

Overview

The skill is genuinely aimed at stopping stuck agent tasks, but it uses broad stop triggers and unsafe shared temporary files that make it risky on shared or sensitive systems.

Review before installing. Use this only where users intentionally need an agent-task kill switch, run it as an ordinary user, avoid shared or privileged hosts until the /tmp file handling is fixed, and require explicit confirmation or narrower commands before sending termination signals. Expect that forced termination can lose unsaved work or leave partial state.

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

T09 · Insecure Skill Coding Practices

Error
Location
scripts/handle-stop.sh:176
Finding
TOCTOU Symlink Race in Stop-Flag Creation<![CDATA[ ## Vulnerability Details **File Location**: `scripts/handle-stop.sh`, lines 176–193 **Vulnerability Type**: Predictable temporary file and time-of-check/time-of-use symlink race **Risk Level**: High ### Vulnerable Code ```bash # 安全检查:拒绝符号链接(防止覆盖任意文件攻击) if [ -L "${FLAG_FILE}" ]; then echo "[STOP] 安全拒绝: FLAG_FILE是符号链接: ${FLAG_FILE}" audit_log "REJECTED" "N/A" "Symlink FLAG_FILE rejected" exit 1 fi cat > "${FLAG_FILE}" << EOF { "sessionId": "${SESSION_ID}", "timestamp": $(date +%s%3N), "reason": "${REASON_ESCAPED}", "signal": "SIGINT", "createdBy": "${CURRENT_USER}", "version": "1.0.2" } EOF chmod 0600 "${FLAG_FILE}" ``` ### Technical Analysis The stop flag uses a predictable path under the shared `/tmp` directory. Although the script rejects a symbolic link before writing, the symbolic-link check and the subsequent file creation are separate filesystem operations. A local attacker can replace the checked path with a symbolic link after the `-L` test succeeds but before the shell processes the output redirection. This is a classic time-of-check/time-of-use race. Shell redirection follows symbolic links, so the destination file would be opened and truncated using the privileges of the account running the skill. The subsequent `chmod 0600` can also follow the substituted path and modify the target file's permissions. ### Attack Path 1. The attacker predicts or learns the session ID. 2. The attacker monitors `/tmp/agent-stop-<session-id>.flag`. 3. The interruption script checks that the path is not a symbolic link. 4. Before the `cat > "${FLAG_FILE}"` redirection occurs, the attacker creates or replaces that path with a symbolic link to a victim file. 5. The script follows the symbolic link and truncates or overwrites the victim file. 6. The script may set the victim file's permissions to `0600`. Successful exploitation requires local filesystem access and the ability to win the race. The target must be writable by the accou ...[truncated 528 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Store all runtime state in a private per-user directory, such as `${XDG_RUNTIME_DIR}/task-interrupt-pro`, after verifying that the directory is owned by the current user and has mode `0700`. 2. Create the flag with exclusive, no-follow semantics equivalent to `open(O_WRONLY | O_CREAT | O_EXCL | O_NOFOLLOW, 0600)`. 3. Do not rely on a separate `-L` check because it cannot make a later write atomic. 4. Write the data to a securely created temporary file in the same private directory and atomically rename it to the final path. 5. Verify the opened object with `fstat` before writing, rather than validating only the pathname. 6. Avoid running this process-management helper with elevated privileges unless strictly necessary. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
scripts/create-stop-flag.sh:5
Finding
Arbitrary File Overwrite Through Unsafe Stop-Flag Helper<![CDATA[ ## Vulnerability Details **File Location**: `scripts/create-stop-flag.sh`, lines 5–21 **Vulnerability Type**: Symbolic-link following, unsafe temporary path construction, and invalid JSON generation **Risk Level**: High ### Vulnerable Code ```bash SESSION_ID="$1" REASON="${2:-User requested stop}" if [ -z "$SESSION_ID" ]; then echo "Usage: $0 <sessionId> [reason]" exit 1 fi FLAG_FILE="/tmp/agent-stop-${SESSION_ID}.flag" cat > "$FLAG_FILE" << EOF { "sessionId": "$SESSION_ID", "timestamp": $(date +%s000), "reason": "$REASON" } EOF ``` ### Technical Analysis The helper writes directly to a predictable path in the shared `/tmp` directory without checking whether the path is a symbolic link and without using exclusive file creation. If an attacker pre-creates the flag path as a symbolic link, shell redirection follows it and truncates the linked target. The helper also does not validate `SESSION_ID`. Unlike the core interruption script, it does not enforce the expected `^[a-z0-9]+-[a-z0-9]+$` format. Path separators and other unexpected characters can therefore influence path resolution when corresponding intermediate directories exist. Finally, `SESSION_ID` and `REASON` are inserted directly into JSON without escaping quotes, backslashes, control characters, or newlines. Crafted input can break the JSON structure or inject additional fields. This primarily affects flag integrity, but may become more significant if another component later treats the file as trusted JSON. ### Attack Path 1. The attacker predicts the session ID that an operator or agent will pass to the helper. 2. The attacker creates `/tmp/agent-stop-<session-id>.flag` as a symbolic link to a victim file writable by the helper's execution account. 3. The helper is invoked with the predicted session ID. 4. The shell follows the symbolic link while processing `cat > "$FLAG_FILE"`. 5. The target file is truncated and replaced with attacker-influenced flag content. Alte ...[truncated 1095 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Apply the same strict session-ID validation used by `handle-stop.sh`, such as `^[a-z0-9]+-[a-z0-9]+$`. 2. Move flag files from the global `/tmp` namespace into a private directory owned by the executing user with mode `0700`. 3. Create files atomically with exclusive and no-follow flags; do not overwrite existing files through ordinary shell redirection. 4. Verify file ownership and type using the opened file descriptor. 5. Encode `SESSION_ID` and `REASON` with a real JSON encoder such as `jq`, Python's `json` module, or another correctly implemented serialization helper. 6. Set a restrictive `umask`, such as `umask 077`, before creating runtime files. 7. Return an error if secure file creation fails instead of falling back to an unsafe write. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
scripts/task-template.sh:52
Finding
PID and Lock File Symlink Attacks in Task Template<![CDATA[ ## Vulnerability Details **File Location**: `scripts/task-template.sh`, lines 52–67 **Vulnerability Type**: Predictable temporary PID and lock files opened without no-follow protection **Risk Level**: High ### Vulnerable Code ```bash # ------------------------------------------------------------------------------ # PID文件写入(使用flock原子锁,防止竞争条件) # ------------------------------------------------------------------------------ write_pid() { if command -v flock >/dev/null 2>&1; then # 有flock,用原子锁写入 flock -n 200 -c "echo $$ > '${PID_FILE}' && chmod 0600 '${PID_FILE}'" 200>"${PID_FILE}.lock" 2>/dev/null || { echo "[TEMPLATE] flock锁定失败,使用直接写入" echo $$ > "${PID_FILE}" chmod 0600 "${PID_FILE}" } else # 无flock,直接写入 echo $$ > "${PID_FILE}" chmod 0600 "${PID_FILE}" fi } ``` ### Technical Analysis Both `${PID_FILE}` and `${PID_FILE}.lock` use predictable names in `/tmp`. The lock-file redirection and PID-file redirection follow symbolic links. `flock` only coordinates processes that cooperate by locking the same opened object. It does not make pathname resolution safe, prevent symbolic-link traversal, or guarantee exclusive secure file creation. Consequently, an attacker can prepare either predictable path as a symbolic link before the task starts. The fallback is especially problematic because any lock failure causes an unconditional direct write to the PID path. This preserves availability at the cost of bypassing the intended locking protection. The PID write truncates the target and replaces its contents with the shell PID. The subsequent `chmod 0600` may also change the target file's permissions. ### Attack Path 1. The attacker predicts or learns the task's session ID. 2. Before the task template starts, the attacker creates one of the following: - `/tmp/agent-pid-<session-id>.pid` as a symbolic link to a victim file; or - `/tmp/agent-pid-<session-id>.pi ...[truncated 1140 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Place PID and lock files in a private per-user runtime directory with mode `0700`. 2. Securely create the PID and lock files with exclusive, no-follow semantics before using them. 3. Retain and lock an already validated file descriptor instead of reopening a predictable pathname inside `flock -c`. 4. Verify ownership, regular-file type, and link count through `fstat` on the opened descriptor. 5. Remove the unsafe direct-write fallback. If secure locking or creation fails, terminate with an error. 6. Use `umask 077` before creating any runtime state. 7. Clean up only files proven to be owned by the current task, and avoid pathname-only deletion after ownership may have changed. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/handle-stop.sh:17
Finding
Shared Audit Log Allows Symlink Redirection and Log Forgery<![CDATA[ ## Vulnerability Details **File Location**: `scripts/handle-stop.sh`, lines 17–30 **Vulnerability Type**: Unsafe shared log file and unsanitized multiline log fields **Risk Level**: Medium ### Vulnerable Code ```bash CURRENT_USER=$(whoami) AUDIT_LOG="/tmp/agent-interrupt-audit.log" FLAG_DIR="/tmp" PID_DIR="/tmp" # ------------------------------------------------------------------------------ # 审计日志函数 # ------------------------------------------------------------------------------ audit_log() { local status="$1" local pid="$2" local msg="$3" local timestamp timestamp=$(date '+%Y-%m-%d %H:%M:%S') echo "${timestamp} | ${status} | SESSION:${SESSION_ID} | PID:${pid} | USER:${CURRENT_USER} | REASON:${REASON} | ${msg}" >> "${AUDIT_LOG}" 2>/dev/null || true } ``` The same logging pattern also appears in `scripts/task-template.sh` at lines 19 and 37–42: ```bash AUDIT_LOG="/tmp/agent-interrupt-audit.log" audit_log() { local status="$1" local msg="$2" local timestamp timestamp=$(date '+%Y-%m-%d %H:%M:%S') echo "${timestamp} | ${status} | SESSION:${SESSION_ID} | PID:$$ | ${msg}" >> "${AUDIT_LOG}" 2>/dev/null || true } ``` ### Technical Analysis The audit log has a fixed, predictable name in a world-writable shared directory. The scripts append to the path without verifying its type, ownership, or symbolic-link status and without opening it with no-follow protection. A local attacker can pre-create `/tmp/agent-interrupt-audit.log` as a symbolic link to another file. When the script logs an event, shell append redirection follows the symbolic link and writes with the privileges of the script runner. In `handle-stop.sh`, the user-supplied `REASON` is inserted into the log verbatim. Newline and carriage-return characters are not escaped. A crafted reason can therefore create fake lines that resemble legitimate audit events. This compromises audit-log integrity even when no symbolic-link attack occurs. ### Attack P ...[truncated 1246 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Store logs in a private application or per-user state directory instead of a shared `/tmp` pathname. 2. Securely create the log with no-follow semantics and restrictive permissions, then retain a validated file descriptor for subsequent writes. 3. Verify that the log is a regular file owned by the expected user and has an acceptable link count. 4. Encode all untrusted log fields using a structured format such as JSON Lines and a real serializer. 5. Escape or reject carriage returns, line feeds, and other control characters in `REASON`, session identifiers, and messages. 6. If a shared system log is required, use a trusted logging facility such as `logger`/syslog rather than direct append redirection. 7. Apply equivalent changes to both `scripts/handle-stop.sh` and `scripts/task-template.sh`. ]]>
Vulnerability Patterns
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (20)

Tp4

High
Category
MCP Tool Poisoning
Confidence
93% confidence
Finding
The documentation presents the skill as a stop/interruption mechanism, but it also documents companion scripts that can clear stop flags and modify control state in /tmp. That mismatch is security-relevant because a user or agent may trust the skill as purely destructive/interruption-only, while it can also alter the stop state and potentially allow tasks to continue or be resumed unexpectedly.

Chaining Abuse

High
Category
Tool Misuse
Content
chmod 0600 "${PID_FILE}"

# 信号处理(收到 SIGINT/SIGTERM 时优雅退出)
trap 'echo "[TRAP] 收到停止信号"; rm -f "${PID_FILE}"; exit 0' SIGINT SIGTERM

# 主循环(每轮检查 flag)
while true; do
Confidence
75% confidence
Finding
Tool calls are chained to bypass individual safety checks or escalate capabilities beyond what any single tool call would allow.

Ae1

High
Category
analysis-evasion
Content
**路径**: `scripts/handle-stop.sh`
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
**路径**: `scripts/handle-stop.sh`
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
**路径**: `scripts/handle-stop.sh`
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Lp3

Medium
Category
MCP Least Privilege
Confidence
90% confidence
Finding
The skill explicitly describes shell-script-based process control but does not declare any tool scope or allowed-tools restrictions. In an agent ecosystem, undeclared shell capability increases the chance that the skill executes with broader privileges than reviewers or policy expect, making process killing and /tmp state manipulation harder to constrain.

Missing User Warnings

Medium
Confidence
93% confidence
Finding
The skill documents escalation to SIGKILL but does not prominently warn that forced termination can cause data loss, partial writes, corrupted temporary state, or inconsistent downstream workflows. For a process-control skill, omitting this warning increases operational risk because users may invoke it casually without understanding the consequences.

Vague Triggers

Medium
Confidence
90% confidence
Finding
Broad symptom phrases like '进程卡住了' or '任务无响应' can trigger an interruption flow without an explicit, unambiguous stop command. In a multi-agent setting this raises the risk of accidental denial of service, where normal conversational troubleshooting language causes unintended termination of active work.

Vague Triggers

Medium
Confidence
90% confidence
Finding
The workflow says to detect keywords such as '停止' plus an agent name rather than exact trigger phrases. Keyword-based matching for destructive process control is dangerous because it can fire on incidental text, quoted examples, or discussions about stopping, causing unintended process interruption.

Vague Triggers

Medium
Confidence
92% confidence
Finding
The trigger list includes broad natural-language phrases such as '停止我的任务', 'agent任务卡住', and '进程无响应' that can plausibly occur during ordinary conversation about troubleshooting. In a skill that interrupts or kills running subtask processes, accidental activation could terminate legitimate work, causing loss of progress or denial of service to the current agent workflow.

Natural-Language Policy Violations

Medium
Confidence
88% confidence
Finding
The manifest description defines the skill and its triggers entirely in Chinese, with no indication that users may invoke it in other languages or that the skill is intentionally limited to a Chinese-speaking context. This creates a language/locale constraint without visible opt-in or justification.

Natural-Language Policy Violations

Medium
Confidence
95% confidence
Finding
The file’s natural-language comments, usage text, and runtime messages are entirely in Chinese, including error and help output shown to users. Under the stated policy, forcing a specific language without opt-in or justification is a locale-policy violation.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Content
# 目录创建
# ------------------------------------------------------------------------------
mkdir -p "${PID_DIR}" 2>/dev/null || true
chmod 0755 "${PID_DIR}" 2>/dev/null || true

# ------------------------------------------------------------------------------
# PID文件写入(使用flock原子锁,防止竞争条件)
Confidence
80% confidence
Finding
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Content
write_pid() {
    if command -v flock >/dev/null 2>&1; then
        # 有flock,用原子锁写入
        flock -n 200 -c "echo $$ > '${PID_FILE}' && chmod 0600 '${PID_FILE}'" 200>"${PID_FILE}.lock" 2>/dev/null || {
            echo "[TEMPLATE] flock锁定失败,使用直接写入"
            echo $$ > "${PID_FILE}"
            chmod 0600 "${PID_FILE}"
Confidence
80% confidence
Finding
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Content
write_pid() {
    if command -v flock >/dev/null 2>&1; then
        # 有flock,用原子锁写入
        flock -n 200 -c "echo $$ > '${PID_FILE}' && chmod 0600 '${PID_FILE}'" 200>"${PID_FILE}.lock" 2>/dev/null || {
            echo "[TEMPLATE] flock锁定失败,使用直接写入"
            echo $$ > "${PID_FILE}"
            chmod 0600 "${PID_FILE}"
Confidence
80% confidence
Finding
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Content
write_pid() {
    if command -v flock >/dev/null 2>&1; then
        # 有flock,用原子锁写入
        flock -n 200 -c "echo $$ > '${PID_FILE}' && chmod 0600 '${PID_FILE}'" 200>"${PID_FILE}.lock" 2>/dev/null || {
            echo "[TEMPLATE] flock锁定失败,使用直接写入"
            echo $$ > "${PID_FILE}"
            chmod 0600 "${PID_FILE}"
Confidence
80% confidence
Finding
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Content
write_pid() {
    if command -v flock >/dev/null 2>&1; then
        # 有flock,用原子锁写入
        flock -n 200 -c "echo $$ > '${PID_FILE}' && chmod 0600 '${PID_FILE}'" 200>"${PID_FILE}.lock" 2>/dev/null || {
            echo "[TEMPLATE] flock锁定失败,使用直接写入"
            echo $$ > "${PID_FILE}"
            chmod 0600 "${PID_FILE}"
Confidence
80% confidence
Finding
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Content
write_pid() {
    if command -v flock >/dev/null 2>&1; then
        # 有flock,用原子锁写入
        flock -n 200 -c "echo $$ > '${PID_FILE}' && chmod 0600 '${PID_FILE}'" 200>"${PID_FILE}.lock" 2>/dev/null || {
            echo "[TEMPLATE] flock锁定失败,使用直接写入"
            echo $$ > "${PID_FILE}"
            chmod 0600 "${PID_FILE}"
Confidence
80% confidence
Finding
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Natural-Language Policy Violations

Low
Confidence
87% confidence
Finding
The documented invocation phrases and instructions are presented only in Chinese, and the skill behavior appears keyed to those Chinese phrases. The file does not offer alternative language options or state that the skill is intentionally limited to a Chinese-only environment, which is a locale policy concern.

Natural-Language Policy Violations

Low
Confidence
91% confidence
Finding
The natural-language comments describing the script's purpose, usage, and behavior are written only in Chinese. Under the stated policy, forcing a specific language without user opt-in can be a locale/language policy violation, and this file does not offer an alternative language or explain a justified locale restriction.

Static analysis

No suspicious patterns detected.