Preflight Checklist
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.additionalContext with 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
Preflight Checklist
What's Wrong?
The
security-guidanceplugin (2.0.0,plugins/security-guidanceat2bfb629) registers its PostToolUse hook forEdit|Write|MultiEdit|NotebookEdit(hooks/hooks.json:33).main()acceptsNotebookEditand readsnotebook_path(security_reminder_hook.py:2112).patterns.pyputs.ipynbin_PY_EXTS, so the Python rules are meant to cover notebooks.extract_content_from_input()(security_reminder_hook.py:429-440) only handlesWrite(content),Edit(new_string) andMultiEdit(edits). For every other tool it returns"". NotebookEdit carries the cell text innew_source, so for a notebook edit no content-based rule runs: pickle,os.system,eval,yaml.load,torch.loadand 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 thepickle_deserializationreminder throughadditionalContext.Steps to Reproduce
Run the hook directly with synthetic PostToolUse input. Point
HOMEandSECURITY_WARNINGS_STATE_DIRat a scratch directory and pre-touch$STATE/.sdk_bootstrap_spawnedso nothing is installed or spawned:Actual:
exit=0.hookSpecificOutput.additionalContextwith the pickle warning.Suggested fix
With
edit_mode: "delete",new_sourceis absent, so this stays a no-op.Additional Information
pickle.load,torch.loadandnp.load(..., allow_pickle=True)are most common, so this is where the reminders matter most.new_sourceand found nothing. [BUG] security-guidance plugin: valid YAML/JSON that is not a mapping (scalar/list) silently drops ALL user security patterns (AttributeError in _load_user_patterns) #87627, security-guidance: XSS-family substring rules fire on doc/prose files — extend the existing _DOC_EXTS carve-out #83851, fix(security-guidance): skip XSS warnings in docs #85806 and [BUG] security-guidance plugin hook fails on Windows — uses hardcoded python3 #40172 are different security-guidance bugs.