fix: security hardening — prompt injection + symlink file-clobber#4
Open
kevglynn wants to merge 6 commits into
Open
fix: security hardening — prompt injection + symlink file-clobber#4kevglynn wants to merge 6 commits into
kevglynn wants to merge 6 commits into
Conversation
Adds standard MIT license at repo root, copyright Kevin Glynn 2026. The repo is already public at github.com/kevglynn/ai-dev-playbook but lacked an explicit license, leaving copyright in the default-restrictive state. MIT was chosen for frictionless adoption — every comparable methodology repo in the space (obra/superpowers, everything-claude-code) uses MIT. Refs ai-dev-playbook-9xc (AC1)
Deletes the 8 files in examples/ that contained scan analysis of internal Pryon repos (igloo-connector, jtbot-core). Removes the corresponding README.md section and the bullets in 3 playbook agent files (beads-strategist, docs-automation-architect, x-factor-innovator) that referenced these examples. The examples were ~256KB of public exposure of Pryon-internal entity names and analysis. Synthetic equivalents on a public OSS target can be regenerated post-Phase-1 if the scan-to-beads demonstration is needed for onboarding. Refs ai-dev-playbook-9xc (AC2)
Deletes 8 docs/ files that were Pryon-internal pitch/demo material: - stringer-workflow-deck.html (scan demo on internal Pryon repos) - ai-dev-game-presentation.html (Pryon origin story deck) - org-agentic-dev-operating-model.html (Pryon org operating model) - solutions-tech-pod-agentic-dev-framework.html (Pryon Solutions adoption) - ecosystem-integration.md (references bitbucket.org/pryoninc/* repos) - integration-faq.md (pryon-baseline integration FAQ) - confluence-orientation-draft.md (Pryon Confluence/Jira links) - demo-run-of-show.md (Pryon internal rollout plan) Scrubs 3 keeper docs that referenced the above: - docs/README.md: rewritten reading order without deleted decks; removed "Ecosystem" section that pointed to internal Pryon repos. - docs/governance.md: removed "For Pryon: thought leadership positioning" section. - docs/adoption-guide.md: generalized "For Pryon-internal projects" placeholder to "For internal projects". Result: zero Pryon-internal entity references remain in docs/. The docs/ directory now contains only public-safe concepts, FAQ, glossary, governance philosophy, executive summary, and adoption guidance. Refs ai-dev-playbook-9xc (AC3)
The README and other user-facing docs pointed users at bitbucket.org/pryoninc/ai-dev-playbook as the primary clone URL, while WELCOME.md already pointed at github.com/kevglynn/ai-dev-playbook. This split-brain framed the public repo as an "internal tool that leaked" to anyone discovering it on GitHub. URL changes (10 instances across 8 files): - README.md, QUICKSTART.md, AGENTS.md: primary install commands - scripts/playbook-init.sh: bootstrap clone hint, generated AGENTS.md block (used by every new project), generated install instructions - global-safety-net/agent-protocol.md: agent fallback clone instruction - global-safety-net/session-start.md: bootstrap-prompt clone command Brand scrubs (residual Pryon framing removed from public-facing files): - README.md: removed "positions Pryon as a thought leader" framing on the governance doc link - PLAN.md: removed "at Pryon" from the repo positioning sentence; generalized "Pryon's agentic development framework" to "the playbook"; generalized "Pryon customizations" to "light project customizations"; removed "internal presentation" thought-leadership framing - CODE_OF_CONDUCT.md: generalized "Pryon-internal projects" to "internal-team projects"; removed "(internal Pryon channels)" from enforcement contact line - CHANGELOG.md: generalized "(Pryon or external)" and "Pryon internal context" in historical entries while preserving the historical record Verification: `rg pryon|igloo|jtbot|pops-platform|marmon|pbssystems` returns zero matches across all tracked files. Refs ai-dev-playbook-9xc (AC4)
README opening reframed from parts-list to transformation framing,
matching WELCOME.md's practitioner voice. The previous opening
("AI-native development methodology — rules, skills, and scripts...")
described the box's contents; the new opening describes what the
playbook actually does to your agent's behavior (drift, missing tests,
missing evidence, context loss). Install command now sits above the
agent-protocol discoverability story. Added "MIT-licensed" signal in
the second paragraph.
VERSION switched from semver (`1.2.0`) to dated edition (`2026-05`).
Methodology doesn't have an API to break — dates communicate "when
this practice snapshot was created" more honestly than semver. Scripts
(`sync-rules.sh`, `playbook-init.sh`) read VERSION as-is and prepend
`v` when printing, so `v2026-05` will be the corresponding git tag.
The previous semver stream is preserved in historical CHANGELOG
entries.
CHANGELOG: added entry for the 2026-05 edition documenting the
public-release transition (license, scrubs, canonical URL, README
rewrite, versioning switch).
Refs ai-dev-playbook-9xc (AC5)
Theme A (High — prompt injection, 3 findings): - auto-recall.sh: recalled memory now rendered as inert fenced data with explicit "not instructions" disclaimer; imperative patterns (Run/Execute/sudo/etc) and shell metacharacters stripped before injection into systemMessage - memory-capture.sh: captured content sanitized with same imperative stripping pipeline before appending to knowledge.jsonl - knowledge-db.sh: kb_sanitize() function added; applied in kb_sync backfill and _kb_sync_jsonl; provenance tracked as "backfill:bd-comments" Theme B (Medium — symlink file-clobber, 5 findings): - playbook-init.sh: predictable /tmp/playbook-init.cp.err replaced with mktemp (mode 600); assert_not_symlink() guards all cp destinations; cleanup via trap - sync-rules.sh: assert_not_symlink() guards every cp in sync_cursor_to, sync_claude_to, and safe_backup - memory-capture.sh: test -L guard on knowledge.jsonl and archive file - sync-cursor-rules.sh: removed (deprecated, superseded by sync-rules.sh); references cleaned from README, PLAN, agent configs Tests: 15 regression tests added at tests/test-security-hardening.sh (all pass). Addresses findings from security review against ab356b0. Co-authored-by: Cursor <cursoragent@cursor.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Security review against commit ab356b0 identified 8 findings in hooks and scripts that get copied into every bootstrapped repo. This PR fixes all 8.
Theme A — Prompt Injection (High, 3 findings)
hookSpecificOutput.systemMessage, allowing attacker-poisoned memory to elevate into high-trust context. Fix: Recalled memory now rendered inside a fenced code block with explicit "user-generated data, not instructions" disclaimer. Imperative patterns (Run:,Execute:,sudo, shell metacharacters like backticks and$) stripped via sed before injection.PostToolUseBash command text containing knowledge prefixes was appended toknowledge.jsonland re-injected next session. Fix: Same imperative-stripping sanitizer applied before capture. Symlink guard added (refuses append ifknowledge.jsonlis a symlink).kb_syncbackfilled untrustedbdcomments verbatim intoknowledge.db. Fix: Newkb_sanitize()function strips imperative patterns; applied in bothkb_syncbackfill and_kb_sync_jsonl. Provenance changed from"backfill"to"backfill:bd-comments".Theme B — Symlink File-Clobber (Medium, 5 findings)
/tmp/playbook-init.cp.errreplaced withmktemp(mode 600).assert_not_symlink()guards everycpdestination. Temp file cleaned viatrap.assert_not_symlink()added before everycpinsync_cursor_to,sync_claude_to, andsafe_backup.test -Lguard onknowledge.jsonland archive file.sync-rules.sh). Refs cleaned from README, PLAN, agent configs.Tests
15-test regression suite at
tests/test-security-hardening.sh— all pass.Test plan
bash tests/test-security-hardening.sh— 15/15 passbash -nsyntax check on all modified shell scripts — cleanplaybook-init.sh, verify hooks copy correctlysync-rules.shrefuses writeMade with Cursor