Issue
The PreToolUse hook script cbm-code-discovery-gate (installed by codebase-memory-mcp install for Claude Code) uses a predictable filename in /tmp:
GATE=/tmp/cbm-code-discovery-gate-$PPID
find /tmp -name 'cbm-code-discovery-gate-*' -mtime +1 -delete 2>/dev/null
if [ -f "$GATE" ]; then
exit 0
fi
touch "$GATE"
This is vulnerable to a symlink attack: an attacker who can predict $PPID (a small integer) and has write access to /tmp could pre-create a symlink at the predictable path pointing at an arbitrary target file. When the hook's touch "$GATE" runs, it would update the mtime of (or create) the target — potentially confusing other tools, or in shared environments writing into paths the user didn't intend.
The bare [ -f "$GATE" ] check also follows symlinks, so a malicious symlink would silently allow the gate to pass without the script actually creating its expected state file.
Practical risk
Low for single-user dev containers (the $PPID prediction window is narrow and /tmp typically has the sticky bit set). Higher in shared/multi-tenant environments where the script could run with predictable PPIDs alongside untrusted users.
Suggested fix
Two reasonable directions, paraphrased from an automated security review:
(a) mktemp + per-session env var:
: "${CBM_GATE_FILE:=$(mktemp -p "${XDG_RUNTIME_DIR:-/run/user/$(id -u)}" cbm-gate.XXXXXX)}"
GATE="$CBM_GATE_FILE"
(b) User-private state directory:
STATE_DIR="${XDG_STATE_HOME:-$HOME/.local/state}/cbm"
install -d -m 700 "$STATE_DIR"
GATE="$STATE_DIR/gate-$PPID"
Either approach, plus harden the file operations to refuse symlinks:
[ -e "$GATE" ] && [ ! -L "$GATE" ] && exit 0
install -m 600 /dev/null "$GATE"
And tighten the cleanup find to the chosen state dir rather than walking all of /tmp:
find "$STATE_DIR" -maxdepth 1 -type f -name 'gate-*' -mtime +1 -delete
Context
Found via Claude Code's automated commit security review while integrating codebase-memory-mcp v0.6.1 into a multi-agent dev container. The hook is otherwise working well and has been useful for steering agents toward MCP queries before grep — small fix, meaningful security improvement.
Happy to send a PR if helpful; flagging the issue first in case there's a preferred approach upstream.
Issue
The PreToolUse hook script
cbm-code-discovery-gate(installed bycodebase-memory-mcp installfor Claude Code) uses a predictable filename in/tmp:This is vulnerable to a symlink attack: an attacker who can predict
$PPID(a small integer) and has write access to/tmpcould pre-create a symlink at the predictable path pointing at an arbitrary target file. When the hook'stouch "$GATE"runs, it would update the mtime of (or create) the target — potentially confusing other tools, or in shared environments writing into paths the user didn't intend.The bare
[ -f "$GATE" ]check also follows symlinks, so a malicious symlink would silently allow the gate to pass without the script actually creating its expected state file.Practical risk
Low for single-user dev containers (the
$PPIDprediction window is narrow and/tmptypically has the sticky bit set). Higher in shared/multi-tenant environments where the script could run with predictable PPIDs alongside untrusted users.Suggested fix
Two reasonable directions, paraphrased from an automated security review:
(a)
mktemp+ per-session env var:(b) User-private state directory:
Either approach, plus harden the file operations to refuse symlinks:
And tighten the cleanup
findto the chosen state dir rather than walking all of/tmp:Context
Found via Claude Code's automated commit security review while integrating
codebase-memory-mcpv0.6.1 into a multi-agent dev container. The hook is otherwise working well and has been useful for steering agents toward MCP queries before grep — small fix, meaningful security improvement.Happy to send a PR if helpful; flagging the issue first in case there's a preferred approach upstream.