[BUG] security-guidance: pattern reminders never fire for NotebookEdit (new_source is not read)
Preflight Checklist
- [x] I have searched existing issues and this hasn't been reported yet
- [x] This is a single bug report
- [x] I am using the latest version of Claude Code
What's Wrong?
The security-guidance plugin (2.0.0, plugins/security-guidance at 2bfb629) registers its PostToolUse hook for Edit|Write|MultiEdit|NotebookEdit (hooks/hooks.json:33). main() accepts NotebookEdit and reads notebook_path (security_reminder_hook.py:2112). patterns.py puts .ipynb in _PY_EXTS, so the Python rules are meant to cover notebooks.
extract_content_from_input() (security_reminder_hook.py:429-440) only handles Write (content), Edit (new_string) and MultiEdit (edits). For every other tool it returns "". NotebookEdit carries the cell text in new_source, so for a notebook edit no content-based rule runs: pickle, os.system, eval, yaml.load, torch.load and the others. The edit passes silently.
What Should Happen?
A NotebookEdit should be checked the same way as a Write of the same code. pickle.load(...) in a cell should produce the pickle_deserialization reminder through additionalContext.
Steps to Reproduce
Run the hook directly with synthetic PostToolUse input. Point HOME and SECURITY_WARNINGS_STATE_DIR at a scratch directory and pre-touch $STATE/.sdk_bootstrap_spawned so nothing is installed or spawned:
H=plugins/security-guidance/hooks/security_reminder_hook.py
S=$(mktemp -d); mkdir -p $S/state $S/proj; touch $S/state/.sdk_bootstrap_spawned
run() { HOME=$S SECURITY_WARNINGS_STATE_DIR=$S/state CLAUDE_PROJECT_DIR=$S/proj python3 $H; echo "exit=$?"; }
# 1. NotebookEdit with pickle.load in the cell -> no output
echo '{"session_id":"n1","hook_event_name":"PostToolUse","tool_name":"NotebookEdit","cwd":"'$S'/proj","tool_input":{"notebook_path":"'$S'/proj/a.ipynb","cell_id":"c1","new_source":"import pickle\ndata = pickle.load(open(p, \"rb\"))","edit_mode":"replace"}}' | run
# 2. Control: the same line via Edit on a .py file -> pickle reminder
echo '{"session_id":"n2","hook_event_name":"PostToolUse","tool_name":"Edit","cwd":"'$S'/proj","tool_input":{"file_path":"'$S'/proj/a.py","old_string":"x","new_string":"data = pickle.load(open(p, \"rb\"))"}}' | run
Actual:
- Case 1 prints only
exit=0. - Case 2 prints
hookSpecificOutput.additionalContextwith the pickle warning.
Suggested fix
elif tool_name == "NotebookEdit":
return tool_input.get("new_source", "") or ""
With edit_mode: "delete", new_source is absent, so this stays a no-op.
Additional Information
- Why it matters: notebooks are where
pickle.load,torch.loadandnp.load(..., allow_pickle=True)are most common, so this is where the reminders matter most. - Searched first: I searched issues and PRs for security-guidance + NotebookEdit/notebook/
new_sourceand found nothing. #87627, #83851, #85806 and #40172 are different security-guidance bugs. - Versions: Claude Code 2.1.289 (VS Code extension), Linux / WSL2. The bug is in the plugin script itself, so platform doesn't matter.
- Disclosure: found while auditing with AI tooling; reproduced by hand with the commands above.
This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗