penthera 1.6.1 → 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.
- package/CHANGELOG.md +296 -0
- package/README.md +217 -322
- package/SECURITY.md +8 -6
- package/bin/scan.js +2 -2
- package/docs/examples/github-actions-scan.yml +1 -1
- package/docs/examples/pr-dependency-review.yml +1 -1
- package/lib/adaptive-probes.js +3 -3
- package/lib/agents/hidden-content.js +122 -11
- package/lib/agents/index.js +26 -6
- package/lib/agents/lock.js +33 -5
- package/lib/agents/rules.js +33 -4
- package/lib/crawler.js +4 -15
- package/lib/deps/capabilities.js +21 -5
- package/lib/deps/index.js +46 -7
- package/lib/deps/iocs.js +74 -0
- package/lib/deps/lockfile.js +3 -8
- package/lib/deps/online.js +8 -3
- package/lib/deps/popular-packages.json.gz +0 -0
- package/lib/deps/popular-pypi.json.gz +0 -0
- package/lib/deps/python/capabilities.js +16 -3
- package/lib/deps/python/index.js +5 -1
- package/lib/deps/python/lockfiles.js +11 -5
- package/lib/deps/python/source.js +75 -26
- package/lib/deps/python/toml.js +15 -3
- package/lib/deps/source.js +28 -9
- package/lib/deps/typosquat.js +30 -5
- package/lib/fix/apply.js +253 -34
- package/lib/fix/index.js +7 -4
- package/lib/fix/model.js +25 -5
- package/lib/fix/util.js +6 -2
- package/lib/fuzzer.js +3 -3
- package/lib/git.js +65 -0
- package/lib/hook/index.js +157 -73
- package/lib/hook/policy.js +10 -4
- package/lib/install/index.js +4 -7
- package/lib/machine.js +0 -13
- package/lib/memory/store.js +11 -4
- package/lib/nuclei-loader.js +0 -25
- package/lib/plugins.js +1 -1
- package/lib/recon.js +12 -31
- package/lib/references.json +44 -0
- package/lib/retirejs.js +4 -4
- package/lib/rules/allowed_signers +13 -0
- package/lib/rules/core/agent-exec.json +29 -0
- package/lib/rules/core/agent-instructions.json +17 -0
- package/lib/rules/core/pack.json +30 -0
- package/lib/rules/core/pack.json.sig +6 -0
- package/lib/rules/core/secrets.json +161 -0
- package/lib/rules/core/templates.json +52 -0
- package/lib/rules/index.js +107 -0
- package/lib/rules/ioc-2025-2026/files.json +43 -0
- package/lib/rules/ioc-2025-2026/hosts.json +35 -0
- package/lib/rules/ioc-2025-2026/pack.json +25 -0
- package/lib/rules/ioc-2025-2026/pack.json.sig +6 -0
- package/lib/rules/ioc-2025-2026/packages.json +1048 -0
- package/lib/rules/pack.js +362 -0
- package/lib/rules/regex-guard.js +81 -9
- package/lib/rules/sshsig.js +205 -0
- package/lib/templates.js +24 -20
- package/lib/tmp.js +21 -0
- package/lib/whitebox/frameworks.js +37 -1
- package/lib/whitebox/secrets.js +117 -41
- package/package.json +11 -4
- package/scripts/rules/build-pack.mjs +80 -0
- package/scripts/rules/check-bundled.mjs +30 -0
- package/scripts/rules/sign-pack.sh +32 -0
- package/skills/penthera/SKILL.md +31 -17
- package/src/agent/git.js +147 -14
- package/src/agent/loop.js +165 -46
- package/src/cli/agent.js +11 -5
- package/src/cli/deps.js +1 -3
- package/src/cli/detect.js +132 -0
- package/src/cli/fix.js +26 -8
- package/src/cli/hook.js +2 -1
- package/src/cli/onboarding.js +436 -6
- package/src/cli/prompt.js +42 -0
- package/src/cli/report-outputs.js +1 -0
- package/src/cli/rules.js +144 -0
- package/src/cli/ui.js +43 -10
- package/src/cli.js +41 -5
- package/src/report/evidence.js +105 -21
- package/src/report/md-escape.js +8 -0
- package/src/scan-url.js +2 -2
- package/src/ui/api/data.js +69 -6
- package/src/ui/api/demo.js +13 -0
- package/src/ui/api/routes.js +45 -11
- package/src/ui/api/runs.js +32 -7
- package/src/ui/security.js +20 -23
- package/src/ui/server.js +52 -27
- package/src/ui/static/app.css +671 -575
- package/src/ui/static/favicon.svg +1 -1
- package/src/ui/static/fonts/DepartureMono-LICENSE.txt +93 -0
- package/src/ui/static/fonts/DepartureMono-Regular.woff2 +0 -0
- package/src/ui/static/index.html +10 -40
- package/src/ui/static/js/api.js +114 -6
- package/src/ui/static/js/app.js +144 -107
- package/src/ui/static/js/center.js +501 -0
- package/src/ui/static/js/charts.js +99 -18
- package/src/ui/static/js/copy.js +95 -62
- package/src/ui/static/js/dialog.js +152 -0
- package/src/ui/static/js/dom.js +0 -38
- package/src/ui/static/js/left.js +46 -0
- package/src/ui/static/js/menubar.js +170 -0
- package/src/ui/static/js/onboarding.js +104 -0
- package/src/ui/static/js/panels.js +186 -0
- package/src/ui/static/js/right.js +151 -0
- package/src/ui/static/js/state.js +66 -0
- package/src/ui/static/logo.svg +10 -0
- package/src/ui/static/mark.svg +3 -0
- package/src/utils/http.js +162 -13
- package/docs/METHODOLOGY.md +0 -321
- package/docs/commands/README.md +0 -23
- package/docs/commands/action.md +0 -21
- package/docs/commands/agents.md +0 -38
- package/docs/commands/deps.md +0 -115
- package/docs/commands/fix.md +0 -53
- package/docs/commands/hook.md +0 -69
- package/docs/commands/install.md +0 -53
- package/docs/commands/scan.md +0 -100
- package/docs/commands/skill.md +0 -58
- package/docs/compare/README.md +0 -25
- package/docs/compare/github.md +0 -60
- package/docs/compare/semgrep.md +0 -54
- package/docs/compare/snyk.md +0 -62
- package/docs/compare/socket.md +0 -78
- package/docs/compare/zap.md +0 -59
- package/docs/compliance-cra.md +0 -141
- package/docs/compliance-nis2.md +0 -168
- package/docs/dashboard.md +0 -244
- package/docs/evidence.md +0 -162
- package/docs/funding/due-diligence-checklist.md +0 -79
- package/docs/funding/nlnet-ngi-zero-draft.md +0 -273
- package/docs/funding/partner-one-pager.md +0 -84
- package/docs/funding/sponsor-tiers.md +0 -81
- package/docs/index.md +0 -81
- package/docs/internal-audit.md +0 -83
- package/docs/local-loop.md +0 -276
- package/docs/marketing.md +0 -151
- package/docs/owasp-wstg-coverage.md +0 -79
- package/docs/plan.md +0 -101
- package/docs/privacy.md +0 -38
- package/docs/references.bib +0 -549
- package/docs/references.md +0 -78
- package/docs/release-plan.md +0 -228
- package/docs/research/socket-positioning-notes.md +0 -183
- package/docs/use-cases/README.md +0 -14
- package/docs/use-cases/agencies.md +0 -71
- package/docs/use-cases/ai-coding-teams.md +0 -81
- package/docs/use-cases/eu-sme-compliance.md +0 -68
- package/docs/use-cases/open-source-maintainers.md +0 -75
- package/docs/use-cases/solo-founder.md +0 -65
- package/lib/deps/popular-packages.json +0 -1
- package/lib/deps/popular-pypi.json +0 -1
- package/src/ui/static/js/views/ai.js +0 -68
- package/src/ui/static/js/views/deps.js +0 -96
- package/src/ui/static/js/views/evidence.js +0 -115
- package/src/ui/static/js/views/findings.js +0 -165
- package/src/ui/static/js/views/history.js +0 -92
- package/src/ui/static/js/views/overview.js +0 -184
- package/src/ui/static/js/views/run.js +0 -349
- package/src/ui/static/js/views/settings.js +0 -67
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,270 @@ 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
|
+
|
|
213
|
+
## [1.7.0] - 2026-10-19
|
|
214
|
+
|
|
215
|
+
One view and one command. `npx penthera` now sets Penthera up in a project:
|
|
216
|
+
it detects what is there, asks what to check, runs it offline and offers the
|
|
217
|
+
hook, the PR workflow and the dashboard. `penthera ui` is a single view with
|
|
218
|
+
side panels. The README is rewritten, and the methodology and references
|
|
219
|
+
follow APA 7.
|
|
220
|
+
|
|
221
|
+
### Added
|
|
222
|
+
|
|
223
|
+
- **`penthera init`, the setup wizard** (also `npx penthera` with no arguments
|
|
224
|
+
in a terminal). It detects the project offline (git, framework, npm and
|
|
225
|
+
Python lockfiles, agent config, a dev server on localhost, an existing hook
|
|
226
|
+
or workflow), asks one checklist question, runs the code, dependency and AI
|
|
227
|
+
tooling checks (and the running app, only after you confirm it is yours),
|
|
228
|
+
then shows the grade per area, the three things to fix first and one report
|
|
229
|
+
folder, `reports/penthera-<date>/`. It then offers, one yes/no each, the
|
|
230
|
+
pre-commit hook, a `.github/workflows/penthera.yml` pinned to the release
|
|
231
|
+
commit SHA (shown as a diff first), `reports/` in `.gitignore`, the fix loop
|
|
232
|
+
and the dashboard. `--yes` takes the safe defaults and never scans a URL,
|
|
233
|
+
runs the fix loop or opens the dashboard; `--dry-run` prints the plan.
|
|
234
|
+
Nothing is committed or pushed. See [docs/commands/init.md](docs/commands/init.md).
|
|
235
|
+
|
|
236
|
+
### Changed
|
|
237
|
+
|
|
238
|
+
- **`penthera ui` is one view, like the Claude Code desktop app.** A
|
|
239
|
+
collapsible left sidebar lists projects (grade, open findings, last scan)
|
|
240
|
+
and recent runs grouped by project, with "+ New scan" on top and settings
|
|
241
|
+
behind a gear. The centre is one scrolling stream: the selected project's
|
|
242
|
+
header (grade, severity bar, trend sparkline), what changed since the last
|
|
243
|
+
scan, "Fix first" and the findings; a running scan or fix loop streams there
|
|
244
|
+
as a transcript with Apply / Skip / Stop inline on each diff. A prompt-style
|
|
245
|
+
bar starts scans, dependency checks, AI tooling audits and the fix loop. The
|
|
246
|
+
collapsible right panel stacks Environment (egress, folder, git branch),
|
|
247
|
+
Memory, Dependencies, AI tooling, Evidence and Changes cards, and shows a
|
|
248
|
+
finding's detail when you pick one. `[` and `]` toggle the side panels, which
|
|
249
|
+
become drawers at narrow widths. Calmer chrome, one primary action at a time;
|
|
250
|
+
the themes, `--demo` and every security property are unchanged. New
|
|
251
|
+
`GET /api/env` reads the branch through the agent's hardened git runner.
|
|
252
|
+
- `penthera-scan` keeps the URL-first wizard that `penthera` used to open.
|
|
253
|
+
|
|
254
|
+
### Docs
|
|
255
|
+
|
|
256
|
+
- README rewritten in the voice of "Penthera: Cyber Security Agent". The
|
|
257
|
+
dashboard screenshots now sit directly under the demo GIF; "Get started" leads
|
|
258
|
+
with one command (`npx penthera`); features are grouped as before you deploy,
|
|
259
|
+
what you build with, and after you ship; and a new "Research and
|
|
260
|
+
methodology" section gives the method, the benchmark numbers, and how to cite
|
|
261
|
+
Penthera. About 12 KB, down from 19 KB.
|
|
262
|
+
- `docs/references.md` is rendered in APA 7th edition style from
|
|
263
|
+
`docs/references.bib`, sorted by first author within each topic, with an
|
|
264
|
+
anchor per BibTeX key. Editors for the three Springer proceedings and the NDSS
|
|
265
|
+
proceedings titles were added from Crossref. A test covers the formatter.
|
|
266
|
+
- `docs/METHODOLOGY.md` uses APA in-text citations, opens with an abstract and
|
|
267
|
+
a "How to cite" block that mirrors `CITATION.cff`, and now cites every
|
|
268
|
+
reference. A test fails if a citation does not resolve or a reference is
|
|
269
|
+
never cited, and the internal audit checks the "How to cite" version.
|
|
270
|
+
|
|
7
271
|
## [1.6.1] - 2026-10-19
|
|
8
272
|
|
|
9
273
|
The GitHub Action gets its Marketplace name. Nothing else changes.
|
|
@@ -82,6 +346,38 @@ reproduced; each fix has a regression test that fails without it.
|
|
|
82
346
|
|
|
83
347
|
### Added
|
|
84
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
|
|
85
381
|
- **Internal testing audit** (`npm run audit:internal`), the release gate:
|
|
86
382
|
tests, benchmark drift, a self-scan against `audit/baseline.json`, a CLI
|
|
87
383
|
smoke matrix, package contents and size, zero third-party egress offline,
|