Back to skill

Security audit

backup-chain

Security checks for vulnerabilities and agentic risk

Overview

This is a local backup and restore skill whose file access, archive creation, and optional command hooks are disclosed and aligned with its purpose.

Install only if you want a local CLI-style backup workflow. Review .vault/config.json before running commands, keep archive and stow destinations private when members may include secrets, and treat --allow-cmd-ledger, --allow-external-ledger, and --stow-cmd as explicit trust decisions because they can interact with destinations or commands you provide.

Vulnerability Patterns
  • 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
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (52)

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The supplied code is not an implementation of the described backup-chain skill. It is a compliance/tripwire test script (tests/check_sinks.py) whose primary function is static analysis of scripts/backup_chain.py. It parses Python AST, counts write/process/archive sink calls, checks imports, bans certain dynamic or unsafe APIs, validates a registry file, and reports drift. While related to the backup project as a safety check, its behavior is materially different from the declared end-user purpose. It neither performs backups nor restore/verification/witness workflows; instead it audits another script's side-effect inventory.

Content

No source excerpt is available for this finding.

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 433)May include surrounding context.

md
tripwire (`tests/check_sinks.py`) that enforces part of that in code

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
80% confidence
Finding

Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Content

Scanner excerpt · references/CHANGELOG.md (reported line 229)May include surrounding context.

md
one-line `FAIL: I/O error` with the same exit code (1) a traceback gave.
- **Fixed — the shipped test suite failed 3 of 291 assertions when run as
  root** (agent sandboxes, Docker CI): T30 simulated a failing custody
  destination with `chmod 555`, which root ignores, so the one assertion that
  proves "failed custody keeps the member" failed for the wrong reason. The
  destination is now a path beneath a regular file, which fails for every uid.
  Verified green both as root and as an unprivileged user.

Anti-Refusal Statement

High
Category
Anti-Refusal
Confidence
80% confidence
Finding

Skill instructs the agent to omit warnings, disclaimers, or ethical commentary. Stripping safety caveats hides risk from the user and is a common jailbreak preamble.

Content

Scanner excerpt · references/CHANGELOG.md (reported line 444)May include surrounding context.

md
distribution discipline as any archive: private destinations for
  credential-looking content.
- **An exclude is a silent hole.** Unlike every other risk in this file,
  curation failures produce no warning at build time: a mistyped pattern
  simply removes paths from every future archive, invisibly, forever. The
  compensating controls are human ones — `member list` displays each
  member's patterns, `status` prints raw member sizes so an over-broad

Anti-Refusal Statement

High
Category
Anti-Refusal
Confidence
80% confidence
Finding

Skill instructs the agent to omit warnings, disclaimers, or ethical commentary. Stripping safety caveats hides risk from the user and is a common jailbreak preamble.

Content

Scanner excerpt · references/SECURITY.md (reported line 204)May include surrounding context.

md
distribution discipline as any archive: private destinations for
  credential-looking content.
- **An exclude is a silent hole.** Unlike every other risk in this file,
  curation failures produce no warning at build time: a mistyped pattern
  simply removes paths from every future archive, invisibly, forever. The
  compensating controls are human ones — `member list` displays each
  member's patterns, `status` prints raw member sizes so an over-broad

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
90% confidence
Finding

Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Content

Scanner excerpt · scripts/backup_chain.py (reported line 253)May include surrounding context.

python
"""Apply a permission mode through the fd of a file this process created
    (never by reopening a pathname — see tests/sink_registry.txt). mode=None
    keeps the pre-1.2.1 parity default for internal state files: 0666 & ~umask
    (best effort on platforms without fchmod — Windows keeps mkstemp's
    owner-only mode). An explicit mode — the v1.3.0 archive/receipt default
    is 0600 — is applied VERBATIM: the operator asked for that mode, so the
    ambient umask neither widens nor narrows it (--archive-mode 0644 means

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
95% confidence
Finding

Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Content

Scanner excerpt · tests/test_backup_chain.sh (reported line 212)May include surrounding context.

sh
print('YES' if 'skills/cache.txt' in m['members'] else 'NO')")"
[ "$INARCHIVE" = "NO" ] && ok "out-of-root link NOT in manifest (no external bytes)" || bad "out-of-root link reached the archive"
assert_has "drill still passes with boundary skip" "restore drill: PASS" "$OUT20"
rm -f skills/cache.txt

echo "== T16 broken symlink nested in a directory member (skipped, not a crash) =="
rm -f skills/linked.txt

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
95% confidence
Finding

Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Content

Scanner excerpt · tests/test_backup_chain.sh (reported line 215)May include surrounding context.

sh
rm -f skills/cache.txt

echo "== T16 broken symlink nested in a directory member (skipped, not a crash) =="
rm -f skills/linked.txt
ln -s "$WS_BASE/does-not-exist-15.txt" skills/broken.txt
OUT16="$($BC build --carries 'nested broken symlink' 2>&1)"; RC16=$?
check "build with nested broken symlink does not crash" 0 $RC16

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
95% confidence
Finding

Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Content

Scanner excerpt · tests/test_backup_chain.sh (reported line 220)May include surrounding context.

sh
OUT16="$($BC build --carries 'nested broken symlink' 2>&1)"; RC16=$?
check "build with nested broken symlink does not crash" 0 $RC16
assert_has "broken symlink skipped with a warning" "skipping broken symlink" "$OUT16"
rm -f skills/broken.txt

echo "== T17 'member add'/'member remove' with no path argument; bad recheck input =="
$BC member add >/dev/null 2>&1; check "member add w/o path is refused, not a crash" 2 $?

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
95% confidence
Finding

Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Content

Scanner excerpt · tests/test_backup_chain.sh (reported line 270)May include surrounding context.

sh
R21="$($BC restore "download/$T21A" --target "$TGT21" 2>&1)"
assert_has "refusal explains the fix" "remove or replace the symlink" "$R21"
[ ! -e "$WS_BASE/outside21/note.txt" ] && ok "refused restore wrote nothing outside target" || bad "restore escaped via symlinked dir"
rm -f "$TGT21/docs"

echo "== T22 final-component symlink: conflict, then --overwrite replaces the link itself =="
echo "outside22 bytes" > "$WS_BASE/outside22.txt"

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
95% confidence
Finding

Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Content

Scanner excerpt · tests/test_backup_chain.sh (reported line 380)May include surrounding context.

sh
B25D="$($BC build 2>&1)"; check "traversing output_dir refused" 1 $?
# 6) symlinked output dir: lexical path is inside, resolved path is not
cfgset output_dir '"download"'
rm -rf "$WS5/download"; mkdir "$WS_BASE/evil25-dl"; ln -s "$WS_BASE/evil25-dl" "$WS5/download"
B25E="$($BC build 2>&1)"; check "symlinked output dir refused at build" 1 $?
assert_has "symlink refusal names the resolved escape" "resolves outside" "$B25E"
[ -z "$(ls "$WS_BASE/evil25-dl" 2>/dev/null)" ] && ok "nothing written through the symlink" || bad "archive landed outside via symlink"

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
95% confidence
Finding

Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Content

Scanner excerpt · tests/test_backup_chain.sh (reported line 384)May include surrounding context.

sh
B25E="$($BC build 2>&1)"; check "symlinked output dir refused at build" 1 $?
assert_has "symlink refusal names the resolved escape" "resolves outside" "$B25E"
[ -z "$(ls "$WS_BASE/evil25-dl" 2>/dev/null)" ] && ok "nothing written through the symlink" || bad "archive landed outside via symlink"
rm "$WS5/download"; mkdir "$WS5/download"
# 7) --output stays the operator's per-invocation escape hatch
$BC build --output "$WS_BASE/evil25-out/cli25.tar.gz" >/dev/null 2>&1; check "--output to external path still works (operator voice)" 0 $?
[ -f "$WS_BASE/evil25-out/cli25.tar.gz" ] && ok "archive landed at operator-chosen path" || bad "--output archive missing"

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
95% confidence
Finding

Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Content

Scanner excerpt · tests/test_backup_chain.sh (reported line 400)May include surrounding context.

sh
$BC init --name "My Chain" >/dev/null 2>&1; check "init accepts space-bearing chain name" 0 $?
$BC init --force --name "../evil25" >/dev/null 2>&1; check "init refuses separator-bearing --name" 2 $?
assert_has "refused init left the good config intact" "My Chain" "$($BC status 2>/dev/null)"
rm -f "$WS_BASE/outside25.txt"

echo "== T26 external ledger gate (audit round 5): config proposes, operator disposes =="
WS6="$WS_BASE/ws6"; EXT6="$WS_BASE/ext26"; mkdir -p "$WS6" "$EXT6"; cd "$WS6" || exit 1

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
95% confidence
Finding

Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Content

Scanner excerpt · tests/test_backup_chain.sh (reported line 441)May include surrounding context.

sh
$BC build --carries x --register >/dev/null 2>&1; check "traversing relative ledger.file refused" 1 $?
[ ! -e "$EXT6/evil26b.log" ] && ok "traversing append wrote nothing" || bad "traversal escaped"
# 3) symlink escape: lexical path in-root, resolved target outside
rm -f "$WS6/.vault/ledger.log"   # drop the real ledger from the control build
python3 - "$WS6" "$EXT6" <<'PYEOF'
import os, sys
ws, ext = sys.argv[1], sys.argv[2]

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
95% confidence
Finding

Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Content

Scanner excerpt · tests/test_backup_chain.sh (reported line 455)May include surrounding context.

sh
$BC build --carries x --register >/dev/null 2>&1; check "traversing relative ledger.file refused" 1 $?
[ ! -e "$EXT6/evil26b.log" ] && ok "traversing append wrote nothing" || bad "traversal escaped"
# 3) symlink escape: lexical path in-root, resolved target outside
rm -f "$WS6/.vault/ledger.log"   # drop the real ledger from the control build
python3 - "$WS6" "$EXT6" <<'PYEOF'
import os, sys
ws, ext = sys.argv[1], sys.argv[2]

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
95% confidence
Finding

Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Content

Scanner excerpt · tests/test_backup_chain.sh (reported line 457)May include surrounding context.

sh
$BC build --carries x --register >/dev/null 2>&1; check "traversing relative ledger.file refused" 1 $?
[ ! -e "$EXT6/evil26b.log" ] && ok "traversing append wrote nothing" || bad "traversal escaped"
# 3) symlink escape: lexical path in-root, resolved target outside
rm -f "$WS6/.vault/ledger.log"   # drop the real ledger from the control build
python3 - "$WS6" "$EXT6" <<'PYEOF'
import os, sys
ws, ext = sys.argv[1], sys.argv[2]

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
95% confidence
Finding

Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Content

Scanner excerpt · tests/test_backup_chain.sh (reported line 469)May include surrounding context.

sh
$BC build --carries x --register >/dev/null 2>&1; check "traversing relative ledger.file refused" 1 $?
[ ! -e "$EXT6/evil26b.log" ] && ok "traversing append wrote nothing" || bad "traversal escaped"
# 3) symlink escape: lexical path in-root, resolved target outside
rm -f "$WS6/.vault/ledger.log"   # drop the real ledger from the control build
python3 - "$WS6" "$EXT6" <<'PYEOF'
import os, sys
ws, ext = sys.argv[1], sys.argv[2]

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
95% confidence
Finding

Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Content

Scanner excerpt · tests/test_backup_chain.sh (reported line 734)May include surrounding context.

sh
[ -n "$LAST31" ] && ok "archive copy landed in stow dir" || bad "no archive in stow dir"
B31B="$($BC build --carries 'stow cmd fail' --stow-cmd false 2>&1)"; check "failing stow-cmd does not fail the build" 0 $?
assert_has "failing stow-cmd warns loudly" "stow command failed" "$B31B"
rm -f "$WS_BASE/stow31-stream.bin"
B31C="$($BC build --carries 'stow cmd ok' --stow-cmd "tee -a $WS_BASE/stow31-stream.bin" >/dev/null 2>&1)"
check "passing stow-cmd" 0 $?
[ -s "$WS_BASE/stow31-stream.bin" ] && ok "stow-cmd received archive bytes on stdin" || bad "stow-cmd got nothing"

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · tests/test_backup_chain.sh (reported line 1219)May include surrounding context.

sh
PYEOF
}
WS44="$WS_BASE/ws44"; mkdir -p "$WS44/st"; cd "$WS44" || exit 1
echo secret44 > secret.txt
$BC init >/dev/null 2>&1
# madd44: idempotent member re-add. On the CURRENT tree every evict below
# refuses and the member stays tracked, so this is a no-op; under mutation

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · tests/test_backup_chain.sh (reported line 1226)May include surrounding context.

sh
PYEOF
}
WS44="$WS_BASE/ws44"; mkdir -p "$WS44/st"; cd "$WS44" || exit 1
echo secret44 > secret.txt
$BC init >/dev/null 2>&1
# madd44: idempotent member re-add. On the CURRENT tree every evict below
# refuses and the member stays tracked, so this is a no-op; under mutation

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · tests/test_backup_chain.sh (reported line 1232)May include surrounding context.

sh
PYEOF
}
WS44="$WS_BASE/ws44"; mkdir -p "$WS44/st"; cd "$WS44" || exit 1
echo secret44 > secret.txt
$BC init >/dev/null 2>&1
# madd44: idempotent member re-add. On the CURRENT tree every evict below
# refuses and the member stays tracked, so this is a no-op; under mutation

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · tests/test_backup_chain.sh (reported line 1237)May include surrounding context.

sh
PYEOF
}
WS44="$WS_BASE/ws44"; mkdir -p "$WS44/st"; cd "$WS44" || exit 1
echo secret44 > secret.txt
$BC init >/dev/null 2>&1
# madd44: idempotent member re-add. On the CURRENT tree every evict below
# refuses and the member stays tracked, so this is a no-op; under mutation

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · tests/test_backup_chain.sh (reported line 1244)May include surrounding context.

sh
PYEOF
}
WS44="$WS_BASE/ws44"; mkdir -p "$WS44/st"; cd "$WS44" || exit 1
echo secret44 > secret.txt
$BC init >/dev/null 2>&1
# madd44: idempotent member re-add. On the CURRENT tree every evict below
# refuses and the member stays tracked, so this is a no-op; under mutation

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · tests/test_backup_chain.sh (reported line 1258)May include surrounding context.

sh
PYEOF
}
WS44="$WS_BASE/ws44"; mkdir -p "$WS44/st"; cd "$WS44" || exit 1
echo secret44 > secret.txt
$BC init >/dev/null 2>&1
# madd44: idempotent member re-add. On the CURRENT tree every evict below
# refuses and the member stays tracked, so this is a no-op; under mutation

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
70% confidence
Finding

Without declared permissions the skill's intent is opaque and cannot be validated.

Content

No source excerpt is available for this finding.