penthera 1.7.0 → 1.8.0-rc.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (149) hide show
  1. package/CHANGELOG.md +238 -0
  2. package/README.md +112 -74
  3. package/SECURITY.md +8 -6
  4. package/docs/examples/pr-dependency-review.yml +1 -1
  5. package/lib/adaptive-probes.js +3 -3
  6. package/lib/agents/hidden-content.js +122 -11
  7. package/lib/agents/index.js +26 -6
  8. package/lib/agents/lock.js +33 -5
  9. package/lib/agents/rules.js +33 -4
  10. package/lib/crawler.js +4 -15
  11. package/lib/deps/capabilities.js +21 -5
  12. package/lib/deps/index.js +46 -7
  13. package/lib/deps/iocs.js +74 -0
  14. package/lib/deps/lockfile.js +3 -8
  15. package/lib/deps/online.js +8 -3
  16. package/lib/deps/popular-packages.json.gz +0 -0
  17. package/lib/deps/popular-pypi.json.gz +0 -0
  18. package/lib/deps/python/capabilities.js +16 -3
  19. package/lib/deps/python/index.js +5 -1
  20. package/lib/deps/python/lockfiles.js +11 -5
  21. package/lib/deps/python/source.js +75 -26
  22. package/lib/deps/python/toml.js +15 -3
  23. package/lib/deps/source.js +28 -9
  24. package/lib/deps/typosquat.js +30 -5
  25. package/lib/fix/apply.js +253 -34
  26. package/lib/fix/index.js +7 -4
  27. package/lib/fix/model.js +25 -5
  28. package/lib/fix/util.js +6 -2
  29. package/lib/fuzzer.js +3 -3
  30. package/lib/git.js +65 -0
  31. package/lib/hook/index.js +157 -73
  32. package/lib/hook/policy.js +10 -4
  33. package/lib/install/index.js +4 -7
  34. package/lib/machine.js +0 -13
  35. package/lib/memory/store.js +11 -4
  36. package/lib/nuclei-loader.js +0 -25
  37. package/lib/plugins.js +1 -1
  38. package/lib/recon.js +12 -31
  39. package/lib/references.json +44 -0
  40. package/lib/retirejs.js +4 -4
  41. package/lib/rules/allowed_signers +13 -0
  42. package/lib/rules/core/agent-exec.json +29 -0
  43. package/lib/rules/core/agent-instructions.json +17 -0
  44. package/lib/rules/core/pack.json +30 -0
  45. package/lib/rules/core/pack.json.sig +6 -0
  46. package/lib/rules/core/secrets.json +161 -0
  47. package/lib/rules/core/templates.json +52 -0
  48. package/lib/rules/index.js +107 -0
  49. package/lib/rules/ioc-2025-2026/files.json +43 -0
  50. package/lib/rules/ioc-2025-2026/hosts.json +35 -0
  51. package/lib/rules/ioc-2025-2026/pack.json +25 -0
  52. package/lib/rules/ioc-2025-2026/pack.json.sig +6 -0
  53. package/lib/rules/ioc-2025-2026/packages.json +1048 -0
  54. package/lib/rules/pack.js +362 -0
  55. package/lib/rules/regex-guard.js +81 -9
  56. package/lib/rules/sshsig.js +205 -0
  57. package/lib/templates.js +24 -20
  58. package/lib/tmp.js +21 -0
  59. package/lib/whitebox/frameworks.js +1 -1
  60. package/lib/whitebox/secrets.js +117 -41
  61. package/package.json +11 -4
  62. package/scripts/rules/build-pack.mjs +80 -0
  63. package/scripts/rules/check-bundled.mjs +30 -0
  64. package/scripts/rules/sign-pack.sh +32 -0
  65. package/skills/penthera/SKILL.md +15 -15
  66. package/src/agent/git.js +147 -14
  67. package/src/agent/loop.js +165 -46
  68. package/src/cli/agent.js +11 -5
  69. package/src/cli/deps.js +0 -2
  70. package/src/cli/detect.js +14 -7
  71. package/src/cli/fix.js +26 -8
  72. package/src/cli/hook.js +2 -1
  73. package/src/cli/onboarding.js +14 -6
  74. package/src/cli/report-outputs.js +1 -0
  75. package/src/cli/rules.js +144 -0
  76. package/src/cli/ui.js +43 -10
  77. package/src/cli.js +23 -0
  78. package/src/report/evidence.js +105 -21
  79. package/src/report/md-escape.js +8 -0
  80. package/src/scan-url.js +2 -2
  81. package/src/ui/api/data.js +39 -6
  82. package/src/ui/api/routes.js +44 -11
  83. package/src/ui/api/runs.js +32 -7
  84. package/src/ui/security.js +20 -23
  85. package/src/ui/server.js +52 -27
  86. package/src/ui/static/app.css +583 -213
  87. package/src/ui/static/favicon.svg +1 -1
  88. package/src/ui/static/fonts/DepartureMono-LICENSE.txt +93 -0
  89. package/src/ui/static/fonts/DepartureMono-Regular.woff2 +0 -0
  90. package/src/ui/static/index.html +5 -4
  91. package/src/ui/static/js/api.js +114 -6
  92. package/src/ui/static/js/app.js +81 -42
  93. package/src/ui/static/js/center.js +246 -133
  94. package/src/ui/static/js/charts.js +99 -18
  95. package/src/ui/static/js/copy.js +67 -8
  96. package/src/ui/static/js/dialog.js +152 -0
  97. package/src/ui/static/js/left.js +23 -60
  98. package/src/ui/static/js/menubar.js +170 -0
  99. package/src/ui/static/js/onboarding.js +104 -0
  100. package/src/ui/static/js/panels.js +186 -0
  101. package/src/ui/static/js/right.js +69 -188
  102. package/src/ui/static/js/state.js +36 -5
  103. package/src/ui/static/logo.svg +10 -0
  104. package/src/ui/static/mark.svg +3 -0
  105. package/src/utils/http.js +162 -13
  106. package/docs/METHODOLOGY.md +0 -375
  107. package/docs/commands/README.md +0 -24
  108. package/docs/commands/action.md +0 -21
  109. package/docs/commands/agents.md +0 -38
  110. package/docs/commands/deps.md +0 -115
  111. package/docs/commands/fix.md +0 -53
  112. package/docs/commands/hook.md +0 -69
  113. package/docs/commands/init.md +0 -114
  114. package/docs/commands/install.md +0 -53
  115. package/docs/commands/scan.md +0 -100
  116. package/docs/commands/skill.md +0 -58
  117. package/docs/compare/README.md +0 -25
  118. package/docs/compare/github.md +0 -60
  119. package/docs/compare/semgrep.md +0 -54
  120. package/docs/compare/snyk.md +0 -62
  121. package/docs/compare/socket.md +0 -78
  122. package/docs/compare/zap.md +0 -59
  123. package/docs/compliance-cra.md +0 -141
  124. package/docs/compliance-nis2.md +0 -168
  125. package/docs/dashboard.md +0 -187
  126. package/docs/evidence.md +0 -162
  127. package/docs/funding/due-diligence-checklist.md +0 -79
  128. package/docs/funding/nlnet-ngi-zero-draft.md +0 -273
  129. package/docs/funding/partner-one-pager.md +0 -84
  130. package/docs/funding/sponsor-tiers.md +0 -81
  131. package/docs/index.md +0 -81
  132. package/docs/internal-audit.md +0 -83
  133. package/docs/local-loop.md +0 -276
  134. package/docs/marketing.md +0 -151
  135. package/docs/owasp-wstg-coverage.md +0 -79
  136. package/docs/plan.md +0 -102
  137. package/docs/privacy.md +0 -38
  138. package/docs/references.bib +0 -559
  139. package/docs/references.md +0 -119
  140. package/docs/release-plan.md +0 -228
  141. package/docs/research/socket-positioning-notes.md +0 -183
  142. package/docs/use-cases/README.md +0 -14
  143. package/docs/use-cases/agencies.md +0 -71
  144. package/docs/use-cases/ai-coding-teams.md +0 -81
  145. package/docs/use-cases/eu-sme-compliance.md +0 -68
  146. package/docs/use-cases/open-source-maintainers.md +0 -75
  147. package/docs/use-cases/solo-founder.md +0 -65
  148. package/lib/deps/popular-packages.json +0 -1
  149. package/lib/deps/popular-pypi.json +0 -1
package/CHANGELOG.md CHANGED
@@ -4,6 +4,212 @@ All notable changes to Penthera are documented here. Versioning follows [SemVer]
4
4
 
5
5
  ## [Unreleased]
6
6
 
7
+ ## [1.8.0-rc.1] - 2026-10-20
8
+
9
+ Release candidate for 1.8.0, published on npm's `next` dist-tag
10
+ (`npm install penthera@next`). It becomes 1.8.0 on `latest` after it has run
11
+ on real projects without a blocking issue.
12
+
13
+ ### Security
14
+
15
+ Fixes from a second independent review. Most also apply to 1.7.0; upgrading
16
+ is recommended.
17
+
18
+ - **Dependency scans fail closed.** An npm or Python package that could not be
19
+ read in full (a code file over 64 MB, more files than the reader takes, an
20
+ archive with inconsistent sizes or other structural anomalies, a matched
21
+ artifact that cannot be opened) is now `unscanned`: a high "could not be
22
+ scanned" finding that `penthera install` always holds for approval. The
23
+ Python scanner gained this state. Wheels are capped on the bytes actually
24
+ inflated. Pax global headers that set a size or path are refused. Deeply
25
+ nested `uv.lock`/`poetry.lock` files are a parse error, not a crash.
26
+ - **The fix loop and `fix --apply` run git hardened.** Commit and tag signing,
27
+ signing programs, attribute files and every configured filter driver are
28
+ overridden on every call (`--attr-source` on git 2.40+). Pathspecs are
29
+ literal. Writes are refused when the repository's own config sets
30
+ `filter.*`, `gpg.*` or `include.*`, or on git older than 2.31; the loop then
31
+ does not start, and its one message names the key and how to go on.
32
+ - **The fix loop keeps your uncommitted work.** Dirty files are read with
33
+ `status -z` and re-checked right before every write and commit. Reverts
34
+ restore the exact bytes from before the fix, and only while the file still
35
+ holds what penthera wrote (otherwise the fix is a `conflict` and the file is
36
+ left alone). Commits use `--only`. Plans that touch untracked or ignored
37
+ files are skipped, and every revert step runs even when one fails.
38
+ - **`applyDiff` is all-or-nothing and writes only regular files in the repo.**
39
+ Duplicate and nested paths are refused, a failed apply puts back what it
40
+ wrote, files are replaced through a temp file (never written through a hard
41
+ link), NTFS stream names and 8.3 aliases are refused, and added lines may not
42
+ contain control characters. Approval prompts show control characters as
43
+ escapes.
44
+ - **The pre-commit hook checks everything it should.** Staged content is read
45
+ by object id from NUL-separated output, type changes are included, files
46
+ with NUL bytes are scanned, and a staged file over 16 MB blocks the commit
47
+ (or warns, with `"largeFiles": "warn"`). `hook install` no longer writes
48
+ through a symlinked `pre-commit`.
49
+ - **Secret scanning checks every match.** A placeholder no longer hides a real
50
+ secret of the same rule later in the file. Only regular files are read, with
51
+ a per-file size cap.
52
+ - **Dashboard sessions are bound to the page.** The one-time token travels in
53
+ the URL fragment and is exchanged for a per-tab session sent as an
54
+ `Authorization` header; no cookie is set or accepted. Approvals carry the
55
+ sha256 of the diff shown, and a cut diff says so and needs an explicit
56
+ acknowledgement. A symlinked default `reports/` is refused and every write
57
+ re-checks the folder. Event ids keep counting past the buffer; requests,
58
+ bodies (413), finished runs and open streams are bounded. `--open` no
59
+ longer puts the token on a command line.
60
+ - **Evidence bundles** are built in a private folder and renamed into place,
61
+ and verification never follows a symlinked folder and caps what it reads.
62
+ - **HTTP responses are bounded.** Every body is read with a size cap (counted
63
+ after decompression) and a deadline that covers the body, not just the
64
+ headers. `--offline` compares host and port, and cross-origin redirects drop
65
+ credentials and do not replay request bodies.
66
+ - **Linear-time matching on untrusted text.** Agent-config exec patterns and
67
+ other agent and hook checks no longer backtrack on long input. The rule-pack
68
+ regex guard refuses ambiguous alternation and optional items inside repeated
69
+ groups and end-anchored rescans; community templates use the same guard.
70
+ - **Hostile repos no longer hang or crash scans**: a FIFO is never read, and
71
+ deeply nested JSON is handled; one unreadable agent config becomes a finding
72
+ instead of aborting the run.
73
+ - `--fix-model` never sends a file from outside the repo as context.
74
+ - Installing the hook through pre-commit.com no longer runs the test suite:
75
+ the `prepack` script is gone (publishing still runs `npm test`).
76
+ - Workflows that push or only read no longer keep credentials in the checkout.
77
+ - **The fix loop cannot game its own checker.** A fix diff, from a local
78
+ model or a recipe, may not edit tests, test runner config or the test
79
+ script, Penthera's policy, suppressions, baseline, lock or memory, CI
80
+ workflows, git hooks or lockfiles; `applyDiff` refuses it with `PROTECTED`
81
+ and says to make that change by hand. The loop verifies only against the
82
+ checker the run began with. "Could not fix" is now a recorded outcome
83
+ (`gave_up` in memory, `loopRun.gaveUp`, a summary line): the finding is not
84
+ retried in that run, and a give-up never counts against a recipe. Older
85
+ Penthera versions report a memory chain with `gave_up` events as malformed.
86
+
87
+ ### Added
88
+
89
+ - Release checks in CI (`.github/workflows/install-matrix.yml`): the packed
90
+ tarball is installed into an empty project and run with `npx penthera` on
91
+ Linux, macOS and Windows with Node 22 and 24 (setup wizard dry run, deps,
92
+ agents, repo scan, the pre-commit hook on a real commit, the dashboard's
93
+ token check, bundled rule pack signatures). An upgrade job installs 1.7.0
94
+ from npm, writes memory and dashboard state, upgrades to the tarball and
95
+ checks the old memory chain still verifies and grows. All of it runs under a
96
+ network guard that fails on anything past loopback.
97
+ - Docs as tests: `scripts/docs-commands.mjs` checks every command in the
98
+ README, `docs/` and the skill against `--help` and runs the offline ones on a
99
+ fixture, in `npm test` and against the installed package.
100
+ - Provenance check in CI (`scripts/ci/provenance.mjs`): every commit in a pull
101
+ request that names an AI co-author must carry an `AI-Assisted` line, and the
102
+ other way round.
103
+
104
+ ### Fixed
105
+
106
+ - Windows: `npx penthera` / `penthera init` in a git repository failed with
107
+ "Refusing to write outside the project" for its own `reports/` folder, because
108
+ git prints the repo root with forward slashes. Git roots are now native paths.
109
+ Found by the new Windows install checks.
110
+ - `penthera --help` lists `--rules-signers` and `--allow-unsigned-rules`. Both
111
+ worked and were documented in `docs/rule-packs.md`, but the help left them
112
+ out.
113
+ - `penthera ui`, Advanced mode: a run's transcript no longer shows a stray
114
+ "null" under its title.
115
+
116
+ ### Changed
117
+
118
+ - **`penthera ui` redesigned for people who are not programmers.** A first
119
+ visit runs a three-screen setup (what Penthera does, Simple or Advanced, the
120
+ project and a first check). Simple mode, the default, leads every project
121
+ with a one-sentence verdict ("Not ready to ship: 1 critical problem to fix
122
+ first."), lists problems in plain words, explains each one as what is wrong,
123
+ how sure and what to do, and tells a run as one sentence. Advanced keeps
124
+ everything, now as project tabs (Findings, Dependencies, AI tooling, History,
125
+ Proof) with a severity by confidence triage matrix. A menu bar replaces the
126
+ prompt bar and carries every action with its shortcut and the run status;
127
+ runs start from a New scan window; every change waits in its own window
128
+ (`y`, `n`, `q`). New look: a 1-bit "System" register of tiled windows, dither
129
+ patterns instead of greys, `#0000ed` as the one accent, Departure Mono (OFL,
130
+ self-hosted) for chrome, the serif Penthera wordmark, and a halftone field
131
+ whose density is the open risk. Both themes pass WCAG AA in every state.
132
+ `scripts/dashboard-screenshots.mjs` regenerates the docs screenshots.
133
+ - Smaller npm package: 797 kB to 657 kB packed, 2.3 MB to 1.7 MB unpacked. The
134
+ package ships only `docs/examples/` (the documentation lives on GitHub, and
135
+ README links resolve there), and the popular-package lists for the typosquat
136
+ check are stored gzipped. No behaviour change.
137
+ - Code cleanup, no behaviour change: one git runner (`lib/git.js`), one
138
+ temp-folder helper, one Markdown table-cell escape and one JSON fetch
139
+ helper replace their copies; unused exports and helpers are gone. CI now
140
+ runs `npm run lint` (ESLint, dev-only, minimal rules). Still one runtime
141
+ dependency.
142
+
143
+ ### Docs
144
+
145
+ - **Penthera is described as an open R&D project with a usable tool:** "an
146
+ open-source cyber security agent you can use today, and verify yourself."
147
+ The README, `docs/index.md`, `package.json`, the plugin and marketplace
148
+ manifests, the Agent Skill (trigger phrases kept), the GitHub Action and the
149
+ repository description carry the approved wording. The README has a "How it
150
+ is measured" section (method, evidence, tool) with Wilson intervals next to
151
+ the benchmark numbers, and stays under 14 KB.
152
+ - **One roadmap, one research plan.** `ROADMAP.md` now says what ships next,
153
+ starting with the 1.8.0 feature freeze. `docs/vision-2.0.md` is the research
154
+ plan and holds the quality gates from `docs/plan.md`. `docs/plan.md`,
155
+ `docs/release-plan.md` (v1.2 to v1.4) and the Socket positioning notes moved
156
+ to `docs/archive/`.
157
+ - **Every user-facing page names the question it answers**, for a starter ("is
158
+ my app safe to ship?") or a pro ("how do I put it in CI?"), and
159
+ `docs/index.md` has a Start here path from starter to pro.
160
+ - **Voice guide** (`docs/voice.md`): plain words, short sentences, numbers with
161
+ intervals over adjectives, limits next to claims, no hype. Every user-facing
162
+ page was edited against it.
163
+ - **Release cadence** in CONTRIBUTING: at most one minor release every 2 to 4
164
+ weeks, always through an `-rc.N` on npm's `next` tag, patches for fixes only,
165
+ and a feature freeze before each minor. Current freeze: 1.8.0 = main + #63.
166
+ - Fixed stale facts: SECURITY.md's supported versions (1.2.x to 1.7.x), README
167
+ anchors that no longer existed, Agent Skill links into `docs/` that broke in
168
+ the npm package since the docs stopped shipping there, and the partner brief
169
+ and due diligence notes that still called shipped features "in review".
170
+ - Limitations stated in full: the methodology's "Known limitations" now covers
171
+ every module (deps, AI tooling, fix loop), the evidence (small sample, wide
172
+ intervals, same-team benchmark, single labeller, uncalibrated confidence
173
+ labels), reproducibility, AI-assisted development, and compliance output. The
174
+ 2.0 research program adds "Threats to validity".
175
+ - GenAI disclosure: `docs/genai.md` states how Penthera is built with
176
+ generative AI (models, scale, review gates, licensing, logs), the README has a
177
+ short "How Penthera is built" section (107 of 117 non-merge commits up to
178
+ v1.7.0 written with Claude), and CONTRIBUTING requires an
179
+ `AI-Assisted` trailer on AI-assisted commits. Follows NLnet's generative AI
180
+ policy.
181
+ - `docs/MANIFESTO.md`: what Penthera is today (and is not), seven design
182
+ decisions with their costs and what would change them, and an FAQ. Written to
183
+ be challenged in Discussions.
184
+ - **After the 2026 agent incidents:** `docs/research/agent-incidents-2026.md`
185
+ says what the OpenAI–Hugging Face and Anthropic evaluation incidents mean
186
+ for Penthera, with sources and caveats. `docs/agents-safely.md` is a
187
+ one-page checklist for running AI agents. `docs/research/spec-harness-rules.md`
188
+ specifies planned `harness-*`, `sandbox-*` and `scorer-*` rules (not built
189
+ yet), and the research plan adds E7 and a draft pre-registration for E8
190
+ (do harness guardrails reduce judge tampering?).
191
+ - README: a "Building in public" section linking the CHANGELOG, the freeze, the
192
+ research in progress and the roadmap. Counts refreshed (57 references);
193
+ `npm run docs:numbers` now also counts the secret patterns in the core rule
194
+ pack (20, as the README says, not 8).
195
+ - `docs/genai.md` covers commits since v1.7.0 and how the agents that build
196
+ Penthera are contained; the manifesto says the fix loop cannot edit what
197
+ judges it.
198
+ - `docs/vision-2.0.md`: the plan for 2.0, covering the biggest gaps, an AI roadmap
199
+ (models propose, deterministic checks decide; local models first) and a
200
+ pre-registered research program with sample sizes and safety rules.
201
+ - **An 80-second walkthrough video** (`assets/walkthrough.mp4`, with a poster
202
+ and `walkthrough.vtt` captions) shows `npx penthera`, an offline scan of the
203
+ mock server, `penthera ui --demo` in Simple and Advanced mode, one fix
204
+ approved and the owner report. It is linked from the README and
205
+ `docs/index.md`. `scripts/media/walkthrough.mjs` renders it from demo data
206
+ only, and the Demo media workflow re-renders it on every release.
207
+ - **The terminal GIFs are re-rendered** in the dashboard's black and white
208
+ look. `scan.tape` now writes the README hero (`assets/demo.gif`) directly
209
+ and scans with `--offline`. The `agents` and `deps --diff` tapes rendered a
210
+ "Cannot find module" error, because they ran `bin/penthera.js` by a
211
+ relative path after changing folder; they use an absolute path now.
212
+
7
213
  ## [1.7.0] - 2026-10-19
8
214
 
9
215
  One view and one command. `npx penthera` now sets Penthera up in a project:
@@ -140,6 +346,38 @@ reproduced; each fix has a regression test that fails without it.
140
346
 
141
347
  ### Added
142
348
 
349
+ - **Signed rule packs** (`lib/rules/`, [docs/rule-packs.md](docs/rule-packs.md)):
350
+ detection data (secret formats, hidden-instruction and exec patterns, IOC
351
+ lists, typosquat targets, Nuclei-compatible templates) ships as versioned
352
+ directories. Each pack has a `pack.json` index of SHA-256 hashes, signed
353
+ with `ssh-keygen -Y sign -n penthera-rules`. Penthera verifies the signature
354
+ (in Node; ssh-keygen is not needed at run time), then every hash, the schema
355
+ and every regex, before it loads anything. Packs arrive bundled in a release,
356
+ or by path with `--rules <dir>` (plus `--rules-signers <file>` for your own
357
+ keys). Unsigned packs are refused unless `--allow-unsigned-rules`, which
358
+ warns loudly. Nothing is ever fetched
359
+ - `penthera rules list` and `penthera rules verify <dir>`; tooling in
360
+ `scripts/rules/` (`build-pack.mjs`, maintainer-only `sign-pack.sh`,
361
+ `check-bundled.mjs`). The publish workflow now refuses to stage a release
362
+ whose bundled packs are not signed by a key in `lib/rules/allowed_signers`
363
+ - ReDoS guard for data-supplied regexes (`lib/rules/regex-guard.js`): length
364
+ cap, no backreferences or lookaround, no nested quantifiers, no alternation
365
+ under unbounded repeats, no unbounded quantifier that every start position
366
+ can rescan, and a backtracking budget for overlapping quantifier chains.
367
+ Fuzz-tested: everything it accepts runs in milliseconds on adversarial
368
+ input. The v1.1.1 template guard moved here too, rewritten from a regex
369
+ (itself polynomial on hostile pattern strings, flagged by CodeQL) into a
370
+ linear scan that also catches deeper nesting
371
+ - Bundled `core` pack: 12 AI-provider key formats, the credential-path
372
+ instruction pattern, two exec patterns and the `.env` template moved out of
373
+ code. Behaviour is identical; a test compares against a snapshot of the old
374
+ built-ins
375
+ - Bundled `ioc-2025-2026` pack (**unsigned in this PR; the maintainer signs it
376
+ before release**): s1ngularity/nx versions (GHSA-cxm3-wv7p-598c), Shai-Hulud
377
+ (StepSecurity's list, exfil URL, `bundle.js` by hash), Shai-Hulud 2.0 (Wiz
378
+ Research's CSV, loader file names) and postmark-mcp 1.0.16 to 1.0.18 with its
379
+ exfil domain. `penthera deps` reports hits as critical `deps-ioc` findings
380
+ that cite the source, wherever the package sits in the tree, installed or not
143
381
  - **Internal testing audit** (`npm run audit:internal`), the release gate:
144
382
  tests, benchmark drift, a self-scan against `audit/baseline.json`, a CLI
145
383
  smoke matrix, package contents and size, zero third-party egress offline,
package/README.md CHANGED
@@ -4,7 +4,7 @@
4
4
 
5
5
  <br/><br/>
6
6
 
7
- **Penthera: Cyber Security Agent. Open-source security for the apps and AI systems you ship.**
7
+ **Penthera: an open-source cyber security agent you can use today, and verify yourself.**
8
8
 
9
9
  <br/>
10
10
 
@@ -20,23 +20,33 @@
20
20
 
21
21
  <br/><br/>
22
22
 
23
- | `penthera ui`, dark | `penthera ui`, light |
23
+ | `penthera ui`, Simple, dark | `penthera ui`, Advanced, light |
24
24
  |---|---|
25
- | ![The dashboard in the dark theme: projects, findings, and a finding's detail](assets/dashboard/ui-dark.jpg) | ![The dashboard in the light theme: all projects and the side cards](assets/dashboard/ui-light.jpg) |
25
+ | ![The dashboard in Simple mode, dark: the verdict, problems in plain words and one problem open](assets/dashboard/ui-dark.jpg) | ![The dashboard in Advanced mode, light: a project's tabs, the triage matrix and a finding open](assets/dashboard/ui-light.jpg) |
26
+
27
+ <a href="assets/walkthrough.mp4"><img src="assets/walkthrough-poster.jpg" alt="Walkthrough video: setup, a scan, the dashboard in Simple and Advanced mode, one fix approved, the report" width="760"></a>
28
+
29
+ [Watch the 80-second walkthrough](assets/walkthrough.mp4): setup, a scan, the dashboard, a fix approved, the report. Demo data, no sound, captions in the video.
26
30
 
27
31
  </div>
28
32
 
29
33
  ---
30
34
 
31
- ## The problem
35
+ ## What Penthera is
36
+
37
+ Teams ship apps and AI agents faster than anyone can check them, and most
38
+ security scanners offer no evidence of how well they actually work. Penthera is
39
+ an open-source R&D project that tackles both.
40
+
41
+ **Use it today.** A cyber security agent for your coding tools that runs
42
+ offline on your own machine: it checks your app, its dependencies and your AI
43
+ tooling, and fixes what it can with your approval, through a dashboard that
44
+ works for first-timers and pros alike.
32
45
 
33
- Teams now ship apps and AI agents faster than anyone can secure them. AI writes
34
- much of the code and pulls in the packages, MCP servers, and skills, and on most
35
- teams nobody works on security full time. Attackers have adapted: 2025 and 2026
36
- brought self-spreading npm worms that hijacked AI coding tools, malicious MCP
37
- servers, poisoned agent skills, and leaked AI provider keys. Penthera does the
38
- repeatable security work on your own machine, with rules you can read, so the
39
- people you have can spend their time on judgement.
46
+ **Trust it because it's measured.** Every check is tested in public,
47
+ pre-registered experiments, and the results are published, good or bad. What
48
+ holds up ships in the next release, so Penthera keeps pace with new attacks and
49
+ with EU rules such as NIS2 and the Cyber Resilience Act.
40
50
 
41
51
  ## Get started
42
52
 
@@ -101,7 +111,7 @@ Penthera needs Node.js 22 or later. To run it in a container:
101
111
  | Job | What Penthera does | Command |
102
112
  |---|---|---|
103
113
  | Report and prove | Writes reports for developers, owners, and auditors; a hashed, signable evidence bundle; NIS2 and CRA readiness reports and drafts | [`penthera <url> --audience auditor --evidence out/`](docs/evidence.md) |
104
- | See it all | A local dashboard on 127.0.0.1: one view with your projects, findings in plain words, history, side panels for dependencies, AI tooling and evidence, and the fix loop with Apply, Skip, and Stop per diff | [`penthera ui`](docs/dashboard.md) |
114
+ | See it all | A local dashboard on 127.0.0.1 with a Simple mode for non-programmers: a one-sentence verdict, problems in plain words, a guided setup, and the fix loop with Apply, Skip, and Stop per change. Advanced adds dependencies, AI tooling, history and evidence | [`penthera ui`](docs/dashboard.md) |
105
115
  | Keep watching | Scheduled checks of your production for drift: certificates, headers, new endpoints, keys in bundles, new CVEs in your SBOM | on the [roadmap](ROADMAP.md) |
106
116
 
107
117
  Every finding carries a severity, a confidence label (`confirmed`, `likely`,
@@ -110,60 +120,69 @@ Reports come out as Markdown, JSON, and SARIF for GitHub code scanning. Exit
110
120
  code `1` means critical or high findings. Every command and flag is in
111
121
  [docs/commands/](docs/commands/README.md).
112
122
 
113
- Penthera is not a human pentester, a 24/7 SOC, or incident response. It does
114
- the checks that can be automated reliably and says plainly which ones need a
115
- person.
123
+ ## How it is measured
124
+
125
+ Each feature goes through the same path: **method → evidence → tool.**
126
+
127
+ - **Method.** The [methodology](docs/METHODOLOGY.md) states the threat model,
128
+ what black-box (HTTP) and white-box (source) analysis can and cannot see, the
129
+ confidence model, and the false-positive controls on each probe. Each design
130
+ choice cites the research or standard it rests on: 57 verified references, in
131
+ APA style, in [docs/references.md](docs/references.md).
132
+ - **Evidence.** A benchmark runs on every release, and the release gate fails
133
+ if precision or recall drops by more than 0.02. Experiments that decide what
134
+ ships next are pre-registered in [docs/research/prereg/](docs/research/prereg/)
135
+ before any data is collected, and the results are published either way.
136
+ - **Tool.** What holds up ships in a reviewed, signed release. What does not
137
+ hold up is dropped, and the rules stay.
138
+
139
+ | Measure | Result today |
140
+ |---|---|
141
+ | Precision on the bundled benchmark | 0.86, 95% CI 0.67 to 0.95 (19 true positives, 3 false positives) |
142
+ | Recall on the bundled benchmark | 0.90, 95% CI 0.71 to 0.97 (2 misses, [each one explained](bench/RESULTS.md)) |
143
+ | Requests to non-loopback hosts during the benchmark | 0 |
144
+ | Detection rules, all readable | 14 URL scan templates, 20 secret and AI-key patterns, 15 dependency capabilities, 39 AI-tooling rules, 5 fix recipes |
145
+
146
+ These numbers come from 22 findings in small labs that we wrote ourselves, so
147
+ they catch regressions; they do not measure real-world accuracy. Measuring that
148
+ on real projects is experiment E1, the first step of the
149
+ [research plan](docs/vision-2.0.md). Intervals are Wilson. What Penthera cannot
150
+ see is listed under [Known limitations](docs/METHODOLOGY.md#known-limitations).
151
+ Counts as of 2026-10-20; refresh them with `npm run docs:numbers` and
152
+ `npm run bench`.
153
+
154
+ **Cite this repository** with the button on GitHub or
155
+ [CITATION.cff](CITATION.cff). APA and BibTeX forms are in the
156
+ [methodology](docs/METHODOLOGY.md#how-to-cite).
116
157
 
117
158
  ## Why you can trust it
118
159
 
119
160
  - **Local and offline.** No account, no telemetry, no cloud. `--offline` limits
120
161
  network traffic to the target you named, and every report lists the hosts it
121
- contacted.
122
- - **Deterministic.** Rules you can read, with `file:line` evidence. No model
123
- decides what is malicious.
162
+ contacted ([network use](docs/privacy.md)).
163
+ - **Deterministic.** Rules you can read, with `file:line` evidence. A local
164
+ model may propose a fix; a deterministic re-scan and your tests decide.
124
165
  - **Non-destructive by default.** The default scan sends only requests a
125
166
  browser would send. Payload testing (`--deep`, `--fuzz`, `--all`) is opt-in
126
167
  and asks for confirmation.
127
- - **Never acts behind your back.** The fix loop works on a local branch, asks
128
- before every change by default, and never pushes or opens pull requests.
168
+ - **Asks before it changes anything.** The fix loop works on a local branch,
169
+ asks before every change by default, and never pushes or opens pull requests.
129
170
  - **No update channel to hijack.** Detection rules ship inside reviewed
130
- releases. Nothing is downloaded and executed at run time.
171
+ releases as signed, versioned [rule packs](docs/rule-packs.md). You can add
172
+ your own by path (`--rules <dir>`). Nothing is downloaded and run at run time.
131
173
  - **Releases you can verify.** npm provenance through trusted publishing, a
132
174
  maintainer approval with 2FA for every version, SHA-pinned CI, CodeQL, and
133
175
  OpenSSF Scorecard. Every release passes an
134
176
  [internal audit](docs/internal-audit.md) of eight gates
135
177
  ([latest report](audit/REPORT.md)).
136
178
 
137
- ## Research and methodology
138
-
139
- Penthera's method is written down and tied to the literature. The
140
- [methodology](docs/METHODOLOGY.md) states the threat model, separates what
141
- black-box (HTTP) and white-box (source) analysis can and cannot observe, and
142
- defines a confidence model that keeps heuristics from posing as facts. Each
143
- probe has explicit false-positive controls, such as randomized canaries and
144
- repeated timing measurement, and each design choice cites the research or
145
- standard it rests on: 49 verified references, listed in APA style in
146
- [docs/references.md](docs/references.md).
147
-
148
- | Measure | Result |
149
- |---|---|
150
- | Precision on the bundled benchmark | 0.86 (19 true positives, 3 false positives) |
151
- | Recall on the bundled benchmark | 0.90 (2 misses, [each one explained](bench/RESULTS.md)) |
152
- | Requests to non-loopback hosts during the benchmark | 0 |
153
- | Detection rules, all readable | 14 URL scan templates, 20 secret and AI-key patterns, 15 dependency capabilities, 39 AI-tooling rules, 5 fix recipes |
154
-
155
- The benchmark targets are small and were written by the same people as the
156
- scanner, so the numbers catch regressions rather than measure real-world
157
- accuracy ([limits](bench/RESULTS.md#limits-of-these-numbers)). Counts as of
158
- 2026-10-19; refresh them with `npm run docs:numbers` and `npm run bench`.
159
-
160
- **Cite this repository.** Use the button on GitHub, or the metadata in
161
- [CITATION.cff](CITATION.cff). The APA and BibTeX forms are in the
162
- [methodology](docs/METHODOLOGY.md#how-to-cite).
179
+ Penthera finds known classes of problems, not novel ones, and it does not
180
+ replace a human pentester or incident response. The decisions behind it, its
181
+ limits, and how to challenge them are in the [manifesto and FAQ](docs/MANIFESTO.md).
163
182
 
164
183
  ## How it fits with other tools
165
184
 
166
- Penthera works next to the tools you already use. Its SARIF output goes
185
+ Penthera works next to the tools you already use; its SARIF output goes
167
186
  straight into GitHub code scanning, for example. Each comparison page says where
168
187
  the other tool goes further and how to run the two together.
169
188
 
@@ -176,29 +195,19 @@ the other tool goes further and how to run the two together.
176
195
  | [OWASP ZAP](docs/compare/zap.md) | Dynamic testing of web apps | Your machine or CI | Active and passive scan rules |
177
196
  | [Semgrep](docs/compare/semgrep.md) | Static analysis of your own code | Your machine, CI, cloud platform | Pattern rules, plus a paid cross-file engine |
178
197
 
179
- All comparisons: [docs/compare/](docs/compare/README.md). Corrections are
180
- welcome by pull request.
181
-
182
- ## Use cases
198
+ ## Start here
183
199
 
184
- | You are | Start here |
200
+ | You want to know | Read |
185
201
  |---|---|
186
- | A solo founder or vibecoder about to launch | [Before launch](docs/use-cases/solo-founder.md) |
187
- | A team adopting Claude Code or Cursor | [The AI-tooling supply chain](docs/use-cases/ai-coding-teams.md) |
188
- | An open-source maintainer | [For maintainers](docs/use-cases/open-source-maintainers.md) |
189
- | An EU SME with NIS2 or CRA duties | [Evidence for NIS2 and the CRA](docs/use-cases/eu-sme-compliance.md) ([NIS2 guide](docs/compliance-nis2.md), [CRA guide](docs/compliance-cra.md)) |
190
- | An agency shipping client apps | [A repeatable handover check](docs/use-cases/agencies.md) |
191
-
192
- Compliance output is readiness tooling. It is not a certification and not
193
- legal advice.
194
-
195
- ## Privacy
202
+ | Is my app safe to ship? | [Before launch](docs/use-cases/solo-founder.md), then [scan](docs/commands/scan.md) |
203
+ | Is this package or MCP server safe? | [deps](docs/commands/deps.md), [install](docs/commands/install.md), [agents](docs/commands/agents.md) |
204
+ | How do I put it in CI? | [The GitHub Action](docs/commands/action.md), [scan in CI](docs/commands/scan.md#ci-integration) |
205
+ | What do I give my auditor? | [Evidence bundles](docs/evidence.md), [NIS2](docs/compliance-nis2.md), [CRA](docs/compliance-cra.md) |
206
+ | How do I run the fix loop? | [Fix and verify](docs/commands/fix.md), [the local loop](docs/local-loop.md) |
196
207
 
197
- Penthera has no telemetry and does not phone home. Scan traffic goes to the
198
- target you name, reports stay on your machine, and every scan lists any
199
- third-party host it contacted. With `--offline`, the HTTP client refuses every
200
- host except the target. Which hosts a normal scan may contact, and why, is in
201
- [docs/privacy.md](docs/privacy.md).
208
+ The full map, by situation and from first scan to pro use, is in
209
+ [docs/index.md](docs/index.md). Compliance output is readiness tooling. It is
210
+ not a certification and not legal advice.
202
211
 
203
212
  ## Ethics and authorization
204
213
 
@@ -210,17 +219,46 @@ or harm anyone. Unauthorized testing may break computer-misuse laws such as the
210
219
  US CFAA, the UK Computer Misuse Act, and their EU equivalents. When in doubt, do
211
220
  not scan.
212
221
 
213
- The software is provided "as is", without warranty, for defensive testing of
214
- systems you own or are authorized to test. The author accepts no liability for
215
- misuse, and you are responsible for making sure every scan you run is lawful.
222
+ The software is provided "as is", without warranty. The author accepts no
223
+ liability for misuse, and you are responsible for making sure every scan you
224
+ run is lawful.
225
+
226
+ ## How Penthera is built
227
+
228
+ Penthera is developed with substantial help from generative AI: 91% of the
229
+ commits up to v1.7.0 were written with Claude (Anthropic) through Claude Code,
230
+ directed and reviewed by the maintainer, and marked with a co-author trailer.
231
+ Generated code passes the same gates as any change: tests, CodeQL, an
232
+ independent review, the internal audit, and a 2FA-approved release. Inside the
233
+ product, models only ever propose; deterministic checks decide. The full
234
+ disclosure, and the rules for AI-assisted contributions, are in
235
+ [docs/genai.md](docs/genai.md).
236
+
237
+ ## Building in public
238
+
239
+ What changed, what we are measuring, and what comes next, in one place.
240
+
241
+ | | Where it stands | Read more |
242
+ |---|---|---|
243
+ | **Latest release** | 1.7.0 (2026-10-19): one-command setup (`npx penthera`), the dashboard, signed rule packs | [CHANGELOG](CHANGELOG.md) |
244
+ | **On main, unreleased** | Fixes from a second independent security review, a fix loop that cannot edit the tests that judge it, release checks on Linux, macOS and Windows, docs tested as code | [Unreleased](CHANGELOG.md#unreleased) |
245
+ | **Now** | 1.8.0 feature freeze: fixes only, a release candidate on npm's `next` tag first | [Roadmap: now](ROADMAP.md#now-180-feature-freeze) |
246
+ | **Research** | E1, accuracy on real code, is pre-registered; the benchmark tooling is in review. After the 2026 agent incidents: a checklist for running agents safely and a draft experiment (E8) | [E1 pre-registration](docs/research/prereg/E1-real-world-accuracy.md), [agents safely](docs/agents-safely.md), [what the incidents mean](docs/research/agent-incidents-2026.md) |
247
+ | **Next** | Real-world precision and recall with intervals, published whatever the result | [Roadmap: next](ROADMAP.md#next), [research plan](docs/vision-2.0.md) |
248
+
249
+ Releases are deliberately slow: a feature freeze, an independent review, the
250
+ release checks, and a release candidate before any new minor version. To
251
+ follow along, watch the repository for releases or join the
252
+ [Discussions](https://github.com/danoszz/penthera/discussions).
216
253
 
217
254
  ## Contributing and support
218
255
 
219
256
  Clone the repository and run `npm install`, then `npm test` for the suite and
220
257
  `npm run bench` for precision and recall.
221
- [CONTRIBUTING.md](CONTRIBUTING.md) covers the project layout and the release
222
- checklist, and the [roadmap](ROADMAP.md) shows what is next. Issues and pull
223
- requests are welcome.
258
+ [CONTRIBUTING.md](CONTRIBUTING.md) covers the project layout, the release
259
+ cadence and the release checklist. The [roadmap](ROADMAP.md) shows what ships
260
+ next, and the [research plan](docs/vision-2.0.md) what we measure. Issues and
261
+ pull requests are welcome.
224
262
 
225
263
  Penthera is free. If it caught something before you shipped it, you can
226
264
  [sponsor its maintenance](https://github.com/sponsors/danoszz). Sponsorship pays
package/SECURITY.md CHANGED
@@ -1,13 +1,16 @@
1
1
  # Security Policy
2
2
 
3
+ > **Starter and pro.** For "I found a vulnerability in Penthera itself: how do I
4
+ > report it?"
5
+
3
6
  ## Supported versions
4
7
 
5
8
  Security fixes land on the latest minor release only. Upgrade to get them.
6
9
 
7
10
  | Version | Supported |
8
11
  | ------- | --------- |
9
- | 1.2.x | Yes |
10
- | < 1.2 | No |
12
+ | 1.7.x | Yes |
13
+ | < 1.7 | No |
11
14
 
12
15
  ## Reporting a vulnerability
13
16
 
@@ -21,7 +24,7 @@ scanning a target), please report it privately:
21
24
 
22
25
  Please do **not** open public issues for undisclosed vulnerabilities.
23
26
 
24
- **What to expect.** Penthera is maintained part-time, but security reports come
27
+ **What to expect.** Penthera is maintained part-time, and security reports come
25
28
  first:
26
29
 
27
30
  - Acknowledgement within 3 working days.
@@ -48,6 +51,5 @@ XSS, command injection, API fuzzing).
48
51
 
49
52
  **Only scan systems you own or have explicit written permission to test.**
50
53
  Unauthorized scanning may be illegal in your jurisdiction. Penthera is built for
51
- defensive research and hardening your own applications — see the full
52
- [ethical-use policy](README.md#ethical-use--authorization) and
53
- [disclaimer](README.md#disclaimer) in the README.
54
+ defensive research and hardening your own applications. See
55
+ [Ethics and authorization](README.md#ethics-and-authorization) in the README.
@@ -50,7 +50,7 @@ jobs:
50
50
  (cd "$RUNNER_TEMP/base" && npm ci --ignore-scripts --no-audit --no-fund)
51
51
  npm ci --ignore-scripts --no-audit --no-fund
52
52
 
53
- - uses: danoszz/penthera@0000000000000000000000000000000000000000 # v1.4.0 (replace with the release commit SHA)
53
+ - uses: danoszz/penthera@525895575f4a9bebe911707a43804a934eac0c4a # v1.6.1 (or a later release commit SHA)
54
54
  with:
55
55
  mode: deps
56
56
  fail-on: none # or high / critical to block the merge
@@ -8,7 +8,7 @@
8
8
  * Results feed into the SecurityKnowledgeGraph for chain discovery.
9
9
  */
10
10
 
11
- import { request } from "../src/utils/http.js";
11
+ import { request, readBody } from "../src/utils/http.js";
12
12
 
13
13
  const DEFAULT_TIMEOUT = 10_000;
14
14
 
@@ -26,9 +26,9 @@ async function probe(base, path, opts = {}) {
26
26
  let body = null;
27
27
  const ct = res.headers.get("content-type") || "";
28
28
  if (ct.includes("json")) {
29
- try { body = await res.json(); } catch { body = null; }
29
+ try { body = JSON.parse(await readBody(res)); } catch { body = null; }
30
30
  } else {
31
- try { body = await res.text(); } catch { body = null; }
31
+ try { body = await readBody(res); } catch { body = null; }
32
32
  }
33
33
  return {
34
34
  url: path, status: res.status,