Skip to content

feat(protect): comprehensive demo/test rule gallery + pack-safety guard#66

Merged
patchstackdave merged 11 commits into
mainfrom
feat/protect-demo-gallery
Jul 14, 2026
Merged

feat(protect): comprehensive demo/test rule gallery + pack-safety guard#66
patchstackdave merged 11 commits into
mainfrom
feat/protect-demo-gallery

Conversation

@patchstackdave

@patchstackdave patchstackdave commented Jul 14, 2026

Copy link
Copy Markdown
Contributor

Stacked on #64.

Two things: a loadable demo rule set that showcases many vulnerability classes at once (for demo environments), and a hard guarantee that the demo's real vulnerable dependency never ships to consumers.

Demo gallery

  • examples/protect/demo-rules.json — one bundle spanning all three phases, each rule carrying an _demo { exploit, benign } vector. Generic public signatures, clearly labeled NOT the production corpus.
    • request (WAF): prototype pollution · path traversal · SQLi · XSS · command injection · NoSQL injection · XXE · request-side SSRF
    • response (leak): PII redaction (email, credit-card) on top of the built-in secret rules
    • egress (SSRF): outbound call to a blocklisted exfiltration host
  • gallery.mjs + demo-runner.mjs — run it live (npm run gallery), one row per rule (exploit blocked/redacted, benign allowed), grouped by phase. No vulnerable dependency needed — runs anywhere, zero install.
── request  (WAF) ──
✓ prototype-pollution  exploit blocked · benign allowed
✓ sqli                 exploit blocked · benign allowed
...
── response (leak) ──
✓ pii-exposure         exploit redacted · benign allowed
── egress   (SSRF) ──
✓ exfiltration         exploit blocked · benign allowed
11/11 demonstrations passed across 3 phases.

Never ships the vulnerable dep

The deep demo (demo.mjs, #61) installs a real lodash@4.17.11 (CVE-2019-10744). This PR makes sure that never reaches consumers:

  • tests/pack-safety.test.ts asserts what npm pack would actually publish — fails CI if examples/ (or any lodash artifact) ever enters the tarball.
  • .npmignore excludes examples/ as a backstop beneath the existing files allowlist.

Confirmed today: the tarball is dist/ + 3 docs + package.json0 examples/lodash files. No workspaces, and node_modules is gitignored, so a clone/install never pulls the vulnerable code either.

Tests

Full suite 370 pass (+4: demo-rules ×2, pack-safety ×2), typecheck + build clean. The gallery and the test share one runner, so they can't drift.

🤖 Generated with Claude Code

patchstackdave and others added 4 commits July 14, 2026 12:36
examples/protect/ — a runnable Verified Vulnerability Shielding demo against a REAL
vulnerable dependency (lodash@4.17.11, CVE-2019-10744): exploit works unprotected →
dry-run detects → block rejects the request before the sink → benign still served →
response AWS-key redaction → egress SSRF block → proof line. No app redeploy, no token.

rules.demo.json holds EXAMPLE rules for public CVEs only (clearly labeled) — NOT the
production corpus, which is fetched per-site from the API at runtime. No secrets in-repo.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…guard

Extend Tier-3 response-phase screening (secret-leak redaction / withhold)
beyond the fetch() path to the remaining server surfaces:

- runtime: expose `screenResponse(response)`; wire `{ screenResponses: true }`
  into node() and express() (buffers the outgoing body, then redacts spans or
  withholds via the response rules). Opt-in — buffering can delay a stream, and
  bodies over 512 KiB pass through unscanned. fetch() now shares the same
  screenResp() closure.
- supabase-guard: screen the forwarded upstream response through
  protection.screenResponse (query results can leak secrets/PII). Fails open.
- types: add screenResponse + the screenResponses option; +8 tests
  (tests/protect/response-guards.test.ts) covering node/express/Supabase
  redact, block-withhold, non-text passthrough, dry-run, and opt-in gating.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…ash)

Pins lodash@4.17.11 so the end-to-end demo reproducibly installs the exact
version CVE-2019-10744 targets.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
A loadable, self-validating showcase rule set for demo environments, plus a
hard guarantee that the demo's vulnerable dependency never ships to consumers.

- examples/protect/demo-rules.json: one bundle spanning all three phases —
  request WAF (prototype pollution, path traversal, SQLi, XSS, command
  injection, NoSQL injection, XXE, request-side SSRF), response leak (PII
  email / credit-card redaction on top of the built-in secret rules), and
  egress SSRF (blocklisted exfil host). Each rule carries an `_demo` block
  { exploit, benign } — generic PUBLIC signatures, NOT the production corpus.
- examples/protect/gallery.mjs + demo-runner.mjs: run the bundle live, one row
  per rule (exploit blocked/redacted, benign allowed), grouped by phase. No
  vulnerable dependency needed — runs anywhere with zero install.
- tests/protect/demo-rules.test.ts: asserts every demo rule blocks its exploit
  and passes its benign (via the same runner, so gallery + test never drift).
- tests/pack-safety.test.ts + .npmignore: enforce that `npm pack` never ships
  examples/ (or any lodash artifact). The package.json "files" allowlist
  already excludes it; this makes the invariant fail CI if it's ever loosened.

370 tests pass, typecheck + build clean.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@coderbuds

coderbuds Bot commented Jul 14, 2026

Copy link
Copy Markdown

Comprehensive demo and safety tests integrated with clear structure and comments.

🎯 Quality: 100% Elite · 📦 Size: Large — consider splitting if possible

📈 This month: Your 26th PR — above team average · Averaging Excellent

See how your team is trending →

patchstackdave and others added 4 commits July 14, 2026 14:58
Don't touch npmignore for field-test, outside my zone.
Do not touch field-test.
Document seeding the scaffolded src/integrations/patchstack/rules.json (the
token-less guard fallback) with examples/protect/demo-rules.json via
`patchstack-connect protect`, plus an honest what-fires-where matrix (write-path
+ response rows fire on a tasks app; path/cmd/SSRF need matching routes; egress
needs egress:true in guard.ts). No change to the shipped CLI.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…lock-safe)

The token-less fallback shipped a single stale placeholder rule (marked XSS,
tied to a specific CVE id). Replace it with a small curated starter set that is
safe to block by default — prototype pollution (structural), path traversal,
internal/metadata SSRF, and XSS (<script>/onerror=/javascript:). Deliberately
NOT the broad demo bundle: SQLi/command-injection/XXE regexes false-positive
and this fallback blocks by default. For a many-class demonstration, seed the
file from examples/protect/demo-rules.json (documented in that README).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Base automatically changed from feat/protect-tier3-complete to main July 14, 2026 13:06
patchstackdave and others added 2 commits July 14, 2026 15:11
…lery

# Conflicts:
#	examples/protect/README.md
#	examples/protect/package.json
…caffold guard

- tests/pack-safety: stop shelling `npm pack --json` (its stdout format varies
  across npm 9/10/11 → node 18/20/22 in CI, which broke JSON.parse). Assert the
  authoritative inputs instead — the package.json "files" allowlist can't sweep
  in examples/, and .npmignore lists examples/ as a backstop. Deterministic, no
  subprocess, identical on every Node version.
- scaffold guard.ts: enable `egress: true` so a real install screens the app's
  outbound calls for SSRF (blocks internal / cloud-metadata addresses; allows
  the app's own Supabase host via allowHosts). Previously dormant.
- examples README: the egress-SSRF row now fires on a real install (no longer
  "add egress:true yourself").

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@patchstackdave

Copy link
Copy Markdown
Contributor Author

/review

@patchstackdave patchstackdave merged commit 77d672f into main Jul 14, 2026
4 checks passed
@patchstackdave patchstackdave deleted the feat/protect-demo-gallery branch July 14, 2026 13:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants