penthera 1.5.0 → 1.6.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 +179 -0
- package/README.md +128 -663
- package/bin/scan.js +19 -0
- package/docs/commands/README.md +23 -0
- package/docs/commands/action.md +21 -0
- package/docs/commands/agents.md +38 -0
- package/docs/commands/deps.md +115 -0
- package/docs/commands/fix.md +53 -0
- package/docs/commands/hook.md +69 -0
- package/docs/commands/install.md +53 -0
- package/docs/commands/scan.md +100 -0
- package/docs/commands/skill.md +58 -0
- package/docs/compare/README.md +25 -0
- package/docs/compare/github.md +60 -0
- package/docs/compare/semgrep.md +54 -0
- package/docs/compare/snyk.md +62 -0
- package/docs/compare/socket.md +78 -0
- package/docs/compare/zap.md +59 -0
- package/docs/dashboard.md +244 -0
- package/docs/evidence.md +8 -4
- package/docs/examples/github-actions-deps.yml +4 -4
- package/docs/examples/github-actions-scan.yml +4 -4
- package/docs/index.md +9 -0
- package/docs/internal-audit.md +83 -0
- package/docs/marketing.md +151 -0
- package/docs/plan.md +4 -3
- package/docs/privacy.md +38 -0
- package/docs/references.bib +10 -0
- package/docs/references.md +1 -0
- package/docs/research/socket-positioning-notes.md +183 -0
- package/docs/use-cases/README.md +14 -0
- package/docs/use-cases/agencies.md +71 -0
- package/docs/use-cases/ai-coding-teams.md +81 -0
- package/docs/use-cases/eu-sme-compliance.md +68 -0
- package/docs/use-cases/open-source-maintainers.md +75 -0
- package/docs/use-cases/solo-founder.md +65 -0
- package/lib/blackbox/email-dns.js +5 -0
- package/lib/compliance/questionnaire.js +4 -2
- package/lib/deps/capabilities.js +49 -12
- package/lib/deps/index.js +290 -30
- package/lib/deps/lockfile.js +25 -2
- package/lib/deps/popular-pypi.json +1 -0
- package/lib/deps/python/capabilities.js +447 -0
- package/lib/deps/python/index.js +234 -0
- package/lib/deps/python/lockfiles.js +359 -0
- package/lib/deps/python/source.js +396 -0
- package/lib/deps/python/toml.js +219 -0
- package/lib/deps/report.js +37 -6
- package/lib/deps/source.js +149 -24
- package/lib/deps/typosquat.js +24 -13
- package/lib/fix/apply.js +83 -19
- package/lib/hook/index.js +41 -8
- package/lib/install/index.js +59 -18
- package/lib/install/policy.js +17 -5
- package/lib/memory/repo-suppress.js +11 -3
- package/lib/references.json +77 -0
- package/lib/remediation/index.js +9 -0
- package/lib/retirejs.js +69 -17
- package/lib/rules/regex-guard.js +368 -0
- package/lib/templates.js +13 -6
- package/lib/tls.js +7 -0
- package/lib/whitebox/frameworks.js +8 -5
- package/lib/whitebox/secrets.js +20 -7
- package/package.json +7 -3
- package/skills/penthera/SKILL.md +23 -5
- package/src/cli/deps.js +60 -5
- package/src/cli/evidence.js +14 -4
- package/src/cli/install.js +14 -5
- package/src/cli/report-outputs.js +25 -2
- package/src/cli/ui.js +89 -0
- package/src/cli.js +19 -7
- package/src/report/audience.js +10 -10
- package/src/report/evidence.js +33 -14
- package/src/report/footer.js +11 -0
- package/src/report/markdown.js +6 -3
- package/src/report/md-escape.js +16 -0
- package/src/reporter.js +1 -0
- package/src/scan-url.js +5 -1
- package/src/ui/api/data.js +309 -0
- package/src/ui/api/demo.js +464 -0
- package/src/ui/api/routes.js +134 -0
- package/src/ui/api/runs.js +243 -0
- package/src/ui/api/summarize.js +451 -0
- package/src/ui/security.js +153 -0
- package/src/ui/server.js +186 -0
- package/src/ui/static/app.css +723 -0
- package/src/ui/static/favicon.svg +1 -0
- package/src/ui/static/index.html +57 -0
- package/src/ui/static/js/api.js +29 -0
- package/src/ui/static/js/app.js +138 -0
- package/src/ui/static/js/charts.js +207 -0
- package/src/ui/static/js/copy.js +79 -0
- package/src/ui/static/js/dom.js +120 -0
- package/src/ui/static/js/format.js +42 -0
- package/src/ui/static/js/theme.js +10 -0
- package/src/ui/static/js/typer.js +99 -0
- package/src/ui/static/js/views/ai.js +68 -0
- package/src/ui/static/js/views/deps.js +96 -0
- package/src/ui/static/js/views/evidence.js +115 -0
- package/src/ui/static/js/views/findings.js +165 -0
- package/src/ui/static/js/views/history.js +92 -0
- package/src/ui/static/js/views/overview.js +184 -0
- package/src/ui/static/js/views/run.js +349 -0
- package/src/ui/static/js/views/settings.js +67 -0
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
# Internal testing audit
|
|
2
|
+
|
|
3
|
+
Penthera is a security tool, so its own release bar has to be easy to check.
|
|
4
|
+
The internal audit is that bar: one command that runs every check a release
|
|
5
|
+
needs and writes the result to [`audit/REPORT.md`](../audit/REPORT.md).
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm run audit:internal
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
It exits 1 if any gate fails. A release is only tagged from a commit whose
|
|
12
|
+
audit passed (see the release checklist in
|
|
13
|
+
[CONTRIBUTING.md](../CONTRIBUTING.md#cutting-a-release)). The same audit runs
|
|
14
|
+
every Monday in CI ([`internal-audit.yml`](../.github/workflows/internal-audit.yml))
|
|
15
|
+
so drift shows up between releases.
|
|
16
|
+
|
|
17
|
+
## The gates
|
|
18
|
+
|
|
19
|
+
| Gate | What it checks | Fails when |
|
|
20
|
+
|---|---|---|
|
|
21
|
+
| Test suite | `npm test`, with the live suites pointed at the bundled mock server (`PENTEST_BASE_URL`) | Any test fails |
|
|
22
|
+
| Benchmark | `npm run bench` (offline, seeded) against the **Total** row of the committed [`bench/RESULTS.md`](../bench/RESULTS.md) | Precision or recall drops by more than 0.02, or any request leaves loopback |
|
|
23
|
+
| Self-scan | `penthera --repo .`, `penthera agents .`, `penthera deps .`, and `penthera hook run` on a copy of the tree with every file staged | A high or critical finding is not in [`audit/baseline.json`](../audit/baseline.json), or a baseline entry has no reason |
|
|
24
|
+
| CLI smoke | `--help` for every subcommand, plus a fixture run of each: a mock-server scan in every report format, `agents` on a clean and a malicious fixture, `deps`, `install --dry-run`, `fix --plan`, an evidence bundle and its `verify`, one `agent --loop` iteration (every diff declined), `hook install/uninstall` and `memory show/verify` | Any command exits with an unexpected code or produces the wrong output |
|
|
25
|
+
| Packaging | `npm pack --dry-run` | A file outside the allow-list ships, anything that looks like tests, fixtures, reports or secrets ships, or the package exceeds its size budget |
|
|
26
|
+
| Offline | A full `--all --adaptive --offline` scan of the mock server | The report's `egress` field shows any third-party host |
|
|
27
|
+
| Supply chain | `npm audit --omit=dev`; sha512 integrity for every lockfile entry; install scripts in runtime dependencies (via `penthera deps --prod`); every `uses:` in `.github/workflows`, `action.yml` and `docs/examples` | Any vulnerability, missing integrity, runtime install script, typosquat, action not pinned by commit SHA, or workflow without top-level `permissions:` |
|
|
28
|
+
| Versions and docs | The version in `package.json`, the lockfile, the plugin manifests, `SKILL.md` and `CITATION.cff`; a `CHANGELOG.md` section for it; every relative link in `README.md` and `docs/` | Any mismatch or broken link |
|
|
29
|
+
|
|
30
|
+
Everything runs on this machine against this repo or `127.0.0.1`. The only
|
|
31
|
+
network use is `npm audit` (the npm registry) and, with `--with-docker`,
|
|
32
|
+
pulling the Juice Shop image.
|
|
33
|
+
|
|
34
|
+
## Options
|
|
35
|
+
|
|
36
|
+
| Flag | Effect |
|
|
37
|
+
|---|---|
|
|
38
|
+
| `--only bench,versions-docs` | Run some gates (ids: `tests`, `bench`, `self-scan`, `smoke`, `packaging`, `offline`, `supply-chain`, `versions-docs`, `docker`). Prints results and writes nothing. |
|
|
39
|
+
| `--update-baseline` | Rewrite `audit/baseline.json` from this run's self-scan. New entries get a `TODO` reason, which fails the gate until a person writes one. |
|
|
40
|
+
| `--with-docker` | Add the optional heavier targets below. |
|
|
41
|
+
| `--no-write` | Leave `audit/` untouched. |
|
|
42
|
+
|
|
43
|
+
Command output from each run goes to `audit/logs/` (ignored by git, uploaded
|
|
44
|
+
with the report as the CI artifact).
|
|
45
|
+
|
|
46
|
+
## Optional targets: Juice Shop and crAPI
|
|
47
|
+
|
|
48
|
+
`--with-docker` starts [OWASP Juice Shop](https://github.com/juice-shop/juice-shop)
|
|
49
|
+
on `127.0.0.1:3300`, scans it with the benchmark's `juice-shop` target, and
|
|
50
|
+
removes the container. Pin the image for reproducible numbers with
|
|
51
|
+
`JUICE_SHOP_IMAGE=bkimminich/juice-shop@sha256:...`.
|
|
52
|
+
|
|
53
|
+
[OWASP crAPI](https://github.com/OWASP/crAPI) needs its own Docker Compose
|
|
54
|
+
stack, so the audit scans it only if it is already running at `CRAPI_URL`
|
|
55
|
+
(default `http://127.0.0.1:8888`). Start it with the project's compose file
|
|
56
|
+
first.
|
|
57
|
+
|
|
58
|
+
Both are skipped by default. Neither has labelled ground truth yet, so the
|
|
59
|
+
report lists their finding counts and shows precision and recall as
|
|
60
|
+
"unlabelled" until they are labelled in `bench/ground-truth.json` (see
|
|
61
|
+
[bench/README.md](../bench/README.md#optional-targets)).
|
|
62
|
+
|
|
63
|
+
## When a gate fails
|
|
64
|
+
|
|
65
|
+
- **Tests, smoke, offline, packaging, supply chain, versions:** fix the cause.
|
|
66
|
+
These describe what Penthera promises its users.
|
|
67
|
+
- **Benchmark:** if the change is intended (a new rule that trades a little
|
|
68
|
+
precision for recall, a relabelled target), run `npm run bench`, commit the
|
|
69
|
+
new `bench/RESULTS.md`, and say why in the PR.
|
|
70
|
+
- **Self-scan:** fix the finding. If it is a deliberate fixture, run
|
|
71
|
+
`--update-baseline` and replace the `TODO` with the reason, so the
|
|
72
|
+
acceptance is reviewed like any other change.
|
|
73
|
+
|
|
74
|
+
Thresholds (the 0.02 benchmark drop, the package size budget, the allow-list)
|
|
75
|
+
live at the top of [`scripts/audit/run.mjs`](../scripts/audit/run.mjs).
|
|
76
|
+
Change them in their own PR, never to make a release pass.
|
|
77
|
+
|
|
78
|
+
## The report
|
|
79
|
+
|
|
80
|
+
`audit/REPORT.md` has a pass/fail table with the numbers behind each gate,
|
|
81
|
+
the changes since the previous report (read from a data block at the end of
|
|
82
|
+
the previous file), and per-gate details. Commit it with each release so the
|
|
83
|
+
history of the gate lives in git.
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
# Marketing automation
|
|
2
|
+
|
|
3
|
+
Penthera is maintained by one person with no budget, so the routine parts of
|
|
4
|
+
getting the word out run by themselves. The rule is simple: **automation drafts
|
|
5
|
+
and collects, a person posts.**
|
|
6
|
+
|
|
7
|
+
- No social-media API tokens and no auto-posting. Every post is copied and
|
|
8
|
+
pasted by a person.
|
|
9
|
+
- No analytics, tracking pixels or telemetry. The numbers come from public
|
|
10
|
+
pages and APIs that anyone can read.
|
|
11
|
+
- Every workflow is SHA-pinned and has least-privilege permissions. Workflows
|
|
12
|
+
that write only open issues (`issues: write`). Only the demo-media workflow
|
|
13
|
+
pushes, and only to a `media/*` branch for a PR.
|
|
14
|
+
- Nothing can embarrass the project without a person in the loop: drafts land
|
|
15
|
+
in issues, job summaries, a collapsed release section or a PR.
|
|
16
|
+
|
|
17
|
+
## What runs
|
|
18
|
+
|
|
19
|
+
| Automation | When | Output | Workflow / script |
|
|
20
|
+
|------------|------|--------|-------------------|
|
|
21
|
+
| Release post drafts | Every `v*` tag | LinkedIn (~600 chars) and X/Bluesky (≤280) drafts in the job summary and under "Share this release" in the GitHub Release (the read-only publish job drafts; the release job, which has no checkout, only attaches them) | `publish.yml` → `scripts/marketing/release-post.mjs` |
|
|
22
|
+
| Incident radar | Daily 06:00 UTC | One issue per new malware advisory for a popular npm package (max 5 per run); every other new advisory as a comment on one standing batch issue | `incident-radar.yml` → `scripts/marketing/incident-radar.mjs` |
|
|
23
|
+
| Product-led footer | Every report | One line at the end of Markdown reports, audience reports, the PR comment and the evidence bundle README | `src/report/footer.js` |
|
|
24
|
+
| Demo media | Every published release, on demand | A PR with re-rendered GIFs from `assets/tapes/*.tape` | `demo-media.yml` |
|
|
25
|
+
| Monthly stats | 1st of the month, 07:00 UTC | Issue "Penthera this month: <Month YYYY>" with a table, month-over-month changes and a draft post | `monthly-stats.yml` → `scripts/marketing/monthly-stats.mjs` |
|
|
26
|
+
| Contributor flywheel | When an issue closes | If fewer than 3 `good first issue` issues are open: one reminder issue listing `TODO(good-first-issue)` markers | `contributor-flywheel.yml` → `scripts/marketing/contributor-flywheel.mjs` |
|
|
27
|
+
|
|
28
|
+
### Release post drafts
|
|
29
|
+
|
|
30
|
+
Built from the CHANGELOG section for the tag: the first sentence of the
|
|
31
|
+
summary paragraph, then three bullets (bold-titled entries first, Added before
|
|
32
|
+
Fixed), then the npm and GitHub release links. The X/Bluesky post is counted
|
|
33
|
+
the way Bluesky counts (every character), which also fits X. Run it locally:
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
node scripts/marketing/release-post.mjs --tag v1.4.0
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
The npm release is staged, not live, until a maintainer approves it. Post after
|
|
40
|
+
approving.
|
|
41
|
+
|
|
42
|
+
### Incident radar
|
|
43
|
+
|
|
44
|
+
Reads `/advisories?type=malware&ecosystem=npm` and `ecosystem=pip` from the
|
|
45
|
+
public GitHub Advisory Database, published in the last 48 hours. About 20
|
|
46
|
+
malware advisories appear every day and most are typosquats nobody installs,
|
|
47
|
+
so by default only advisories for packages in `lib/deps/popular-packages.json`
|
|
48
|
+
get their own issue (with the checklist and a draft "check if you're affected
|
|
49
|
+
with one command" post). The rest go into one standing issue, "Incident radar:
|
|
50
|
+
other new malware advisories", one comment per run. Set `mode: all` on a manual
|
|
51
|
+
run to open one issue per advisory instead (still at most 5).
|
|
52
|
+
|
|
53
|
+
State is the issues themselves: an advisory counts as seen when its GHSA id is
|
|
54
|
+
in an `incident-radar` issue or a radar batch comment from the look-back
|
|
55
|
+
window. There is no state file or branch.
|
|
56
|
+
|
|
57
|
+
Each issue's checklist: add the IOCs to a rule pack in `lib/rules/` (or the
|
|
58
|
+
deps rules until rule packs exist), verify `penthera deps` flags a fixture
|
|
59
|
+
lockfile with the package, then post. Do not post before detection is
|
|
60
|
+
verified.
|
|
61
|
+
|
|
62
|
+
### Product-led footer
|
|
63
|
+
|
|
64
|
+
Human-readable Markdown ends with:
|
|
65
|
+
|
|
66
|
+
> Checked by Penthera, open-source security for the apps and AI systems you ship · https://github.com/danoszz/penthera
|
|
67
|
+
|
|
68
|
+
It is never added to SARIF or JSON. Users turn it off with `--no-footer` (CLI)
|
|
69
|
+
or `footer: "false"` (GitHub Action).
|
|
70
|
+
|
|
71
|
+
### Demo media
|
|
72
|
+
|
|
73
|
+
Tapes live in `assets/tapes/` (see its README). The workflow installs
|
|
74
|
+
[VHS](https://github.com/charmbracelet/vhs) with `charmbracelet/vhs-action`,
|
|
75
|
+
renders every tape, uploads the GIFs as a workflow artifact and, unless it is a
|
|
76
|
+
dry run, opens a PR from a `media/*` branch. It needs **Settings → Actions →
|
|
77
|
+
General → Allow GitHub Actions to create and approve pull requests**. PRs
|
|
78
|
+
opened by `GITHUB_TOKEN` do not trigger CI; close and reopen the PR to run it.
|
|
79
|
+
|
|
80
|
+
### Monthly stats
|
|
81
|
+
|
|
82
|
+
Public sources only:
|
|
83
|
+
|
|
84
|
+
- npm downloads for the calendar month (`api.npmjs.org`);
|
|
85
|
+
- stars and forks at run time and PRs merged that month (GitHub API);
|
|
86
|
+
- installs from the public skills.sh skill page;
|
|
87
|
+
- dependent repositories from GitHub's dependents page.
|
|
88
|
+
|
|
89
|
+
Each page is parsed strictly: if the markup changed, the number shows as
|
|
90
|
+
`n/a`, never a guess. The issue keeps its numbers in a hidden JSON comment,
|
|
91
|
+
and next month's issue reads them back for the change column.
|
|
92
|
+
|
|
93
|
+
### Contributor flywheel
|
|
94
|
+
|
|
95
|
+
Write `TODO(good-first-issue): <what to do>` in a comment next to a small,
|
|
96
|
+
well-scoped change. When the open `good first issue` count drops below 3, the
|
|
97
|
+
reminder issue lists these markers with links. Turn one or two into issues,
|
|
98
|
+
then close the reminder. Closing the reminder itself never triggers a new one.
|
|
99
|
+
|
|
100
|
+
## Dry runs
|
|
101
|
+
|
|
102
|
+
Every scheduled workflow has a `workflow_dispatch` trigger whose `dry-run`
|
|
103
|
+
input defaults to **on**: it prints what it would open to the job summary and
|
|
104
|
+
writes nothing.
|
|
105
|
+
|
|
106
|
+
| Workflow | Dry run |
|
|
107
|
+
|----------|---------|
|
|
108
|
+
| Incident radar | Actions → Incident radar → Run workflow (`dry-run` checked; optional `mode`, `since-hours`) |
|
|
109
|
+
| Monthly stats | Actions → Monthly stats → Run workflow (`dry-run` checked; optional `month`, e.g. `2026-09`) |
|
|
110
|
+
| Contributor flywheel | Actions → Contributor flywheel → Run workflow (`dry-run` checked) |
|
|
111
|
+
| Demo media | Actions → Demo media → Run workflow (`dry-run` checked: GIFs as an artifact, no PR) |
|
|
112
|
+
| Release posts | `node scripts/marketing/release-post.mjs --tag vX.Y.Z` locally |
|
|
113
|
+
|
|
114
|
+
From a terminal with the GitHub CLI:
|
|
115
|
+
|
|
116
|
+
```bash
|
|
117
|
+
gh workflow run incident-radar.yml -f dry-run=true
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
The scripts also run locally with `--dry-run` (they use your `gh` login for
|
|
121
|
+
reads only):
|
|
122
|
+
|
|
123
|
+
```bash
|
|
124
|
+
node scripts/marketing/incident-radar.mjs --repo danoszz/penthera --dry-run
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
## Turning things off
|
|
128
|
+
|
|
129
|
+
- **One workflow:** Actions → the workflow → "…" → Disable workflow. Or delete
|
|
130
|
+
its file.
|
|
131
|
+
- **Release drafts:** remove the "Draft release posts" and "Keep the drafts" steps (publish job) and the two share steps (release job) from `publish.yml`.
|
|
132
|
+
- **Footer, for one run:** `--no-footer` or `footer: "false"` in the Action.
|
|
133
|
+
To drop it for everyone, make `footerLines()` in `src/report/footer.js`
|
|
134
|
+
return `[]`.
|
|
135
|
+
- **Labels** (`incident-radar`, `monthly-stats`, `contributor-flywheel`) are
|
|
136
|
+
created on the first real run and can be deleted afterwards.
|
|
137
|
+
|
|
138
|
+
## The weekly 30-minute routine
|
|
139
|
+
|
|
140
|
+
1. **Incident radar (10 min).** Open the `incident-radar` issues. For a
|
|
141
|
+
popular package: add the IOCs, check `penthera deps` flags a fixture, post
|
|
142
|
+
the draft (LinkedIn, X, Bluesky), close the issue. Skim the batch issue for
|
|
143
|
+
names you recognise, then close it if it is long.
|
|
144
|
+
2. **A clip (5 min).** If a demo-media PR is open, watch the GIFs, merge, and
|
|
145
|
+
post the best one as a short clip (Instagram, LinkedIn, X).
|
|
146
|
+
3. **Contributors (5 min).** If the flywheel reminder is open, turn one or two
|
|
147
|
+
markers into `good first issue` issues. Reply to new contributors.
|
|
148
|
+
4. **Release (5 min, when there is one).** Approve the staged npm package, then
|
|
149
|
+
copy the "Share this release" drafts from the GitHub Release, edit, post.
|
|
150
|
+
5. **Monthly (5 min, first week).** Fill in "what shipped" in the stats issue,
|
|
151
|
+
post it, close it.
|
package/docs/plan.md
CHANGED
|
@@ -27,9 +27,10 @@ these three moments is out of scope.
|
|
|
27
27
|
|
|
28
28
|
| Release | Theme | Done when |
|
|
29
29
|
|---------|-------|-----------|
|
|
30
|
-
| v1.5.0 | AI apps and compliance |
|
|
31
|
-
| v1.6.0 |
|
|
32
|
-
| v1.7.0 |
|
|
30
|
+
| v1.5.0 | AI apps and compliance | Tagged with the pre-commit hook, license policy, CRA helper and AI-BOM; held back from npm and shipped inside 1.6.0 |
|
|
31
|
+
| v1.6.0 | Hardening and the rest of AI apps | Released with the 360 security review fixes, Python `deps`, the internal audit gate and the dashboard. Signed rule packs follow once the maintainer's key is set up |
|
|
32
|
+
| v1.7.0 | Before you deploy | `penthera ship` and preview-deployment scanning work on a real Vercel and Netlify project |
|
|
33
|
+
| v1.8.0 | After you ship | `penthera watch` runs weekly on three real production apps for a month without a false alarm anyone complained about |
|
|
33
34
|
| v2.0.0 | Stable | Public interfaces frozen (CLI flags, JSON report schema, policy file, rule-pack format), documented, and covered by compatibility tests |
|
|
34
35
|
|
|
35
36
|
## What "perfect" means, concretely
|
package/docs/privacy.md
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# Privacy and network use
|
|
2
|
+
|
|
3
|
+
Penthera has no telemetry. It does not collect, store, or transmit any usage data, analytics, or personal information to the author or any third party. It does not phone home.
|
|
4
|
+
|
|
5
|
+
- **Scan traffic goes to the target you specify.** Auth tokens passed via `--auth-bearer`, `--auth-cookie`, or `PENTHERA_*` env vars are sent only to that target.
|
|
6
|
+
- **Every request identifies itself** as `penthera/<version> (+https://github.com/danoszz/penthera)`, so a target's operator can tell where the traffic comes from. Override it with `--user-agent`.
|
|
7
|
+
- **Reports stay local.** Output is written to `reports/` (gitignored) on your machine.
|
|
8
|
+
- **Every scan lists the third-party hosts it contacted** besides the target, in the terminal summary and in the report's "Network egress" section.
|
|
9
|
+
|
|
10
|
+
Without `--offline`, a scan may contact these third parties:
|
|
11
|
+
|
|
12
|
+
| Host | When | What it learns |
|
|
13
|
+
|---|---|---|
|
|
14
|
+
| `raw.githubusercontent.com`, `cdn.jsdelivr.net` | Retire.js check (standard and deep profiles) | That someone downloaded the public database. Nothing about your target. |
|
|
15
|
+
| `crt.sh`, `web.archive.org`, `otx.alienvault.com` | `--recon` only | The target domain. |
|
|
16
|
+
| CDN hosts serving your page's `<script src>` | Retire.js check, when a script's version can only be read from its contents | That someone fetched that public script. |
|
|
17
|
+
|
|
18
|
+
### Fully local: `--offline`
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
penthera http://localhost:3000 --offline
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
With `--offline`, the HTTP client refuses every host except the scan target. A redirect may only move to a host on the target's registrable domain (`example.com` to `www.example.com`). In practice:
|
|
25
|
+
|
|
26
|
+
- **Recon is skipped.** No queries go to crt.sh, the Wayback Machine or OTX.
|
|
27
|
+
- **The Retire.js database comes from the snapshot vendored in the package** (`lib/data/retire-jsrepository.json.gz`), refreshed at each release by `scripts/refresh-retire-db.mjs`. The source URL, fetch date and SHA-256 sit next to it in `retire-jsrepository.meta.json`, so you can check it against upstream. Online scans fall back to the snapshot too when the live download fails.
|
|
28
|
+
- **Third-party scripts are not fetched.** A refused request is listed in the report as an inconclusive probe, not passed over silently.
|
|
29
|
+
- **`--suppliers` is refused**, because it rates third-party domains.
|
|
30
|
+
- **DNS:** reaching a remote target needs DNS. For non-local targets, the email-authentication check also looks up the target domain's SPF/DMARC/MX records through your system resolver. A `localhost` or IP target needs no DNS at all.
|
|
31
|
+
|
|
32
|
+
Penthera never fetches rules or code at runtime: templates, wordlists and the vulnerability database ship in the package.
|
|
33
|
+
|
|
34
|
+
### Inconclusive probes
|
|
35
|
+
|
|
36
|
+
When a probe's requests time out, fail, or are refused by `--offline`, the scan records `{ probe, url, message }` in `result.errors`. The terminal summary shows "N probes inconclusive", and the Markdown report lists each one. A probe that could not run is not a clean result.
|
|
37
|
+
|
|
38
|
+
You are responsible for ensuring you are authorized to scan any target. See [Ethical use](../README.md#ethical-use--authorization).
|
package/docs/references.bib
CHANGED
|
@@ -537,3 +537,13 @@
|
|
|
537
537
|
urldate = {2026-10-19},
|
|
538
538
|
note = {standards}
|
|
539
539
|
}
|
|
540
|
+
|
|
541
|
+
@misc{spdxlicenselist,
|
|
542
|
+
shorthand = {SPDX License List},
|
|
543
|
+
author = {{SPDX Workgroup, The Linux Foundation}},
|
|
544
|
+
title = {{SPDX} License List},
|
|
545
|
+
howpublished = {Standardized short identifiers for open source licenses, used by package manifests and SBOMs},
|
|
546
|
+
url = {https://spdx.org/licenses/},
|
|
547
|
+
urldate = {2026-10-19},
|
|
548
|
+
note = {standards}
|
|
549
|
+
}
|
package/docs/references.md
CHANGED
|
@@ -75,3 +75,4 @@ Every entry was checked against the publisher or standards body (Crossref DOI me
|
|
|
75
75
|
- `oasis2023sarif`: Fanning, Michael C.; Golding, Laurence J. (2023). *Static Analysis Results Interchange Format (SARIF) Version 2.1.0 Plus Errata 01*. OASIS Standard incorporating Approved Errata, 28 August 2023. <https://docs.oasis-open.org/sarif/sarif/v2.1.0/errata01/os/sarif-v2.1.0-errata01-os-complete.html>
|
|
76
76
|
- `eu2022nis2`: European Parliament; Council of the European Union (2022). *Directive (EU) 2022/2555 of the European Parliament and of the Council of 14 December 2022 on measures for a high common level of cybersecurity across the Union, amending Regulation (EU) No 910/2014 and Directive (EU) 2018/1972, and repealing Directive (EU) 2016/1148 (NIS 2 Directive)*. Official Journal of the European Union, L 333, 27.12.2022, p. 80. <https://eur-lex.europa.eu/eli/dir/2022/2555/oj>
|
|
77
77
|
- `mitrecwe`: The MITRE Corporation. *CWE: Common Weakness Enumeration*. Community-developed list of software and hardware weakness types, sponsored by CISA. <https://cwe.mitre.org/>
|
|
78
|
+
- `spdxlicenselist`: SPDX Workgroup, The Linux Foundation. *SPDX License List*. Standardized short identifiers for open source licenses, used by package manifests and SBOMs. <https://spdx.org/licenses/>
|
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
# How Socket positions itself: notes for Penthera's docs
|
|
2
|
+
|
|
3
|
+
*Read on 2026-10-19. Everything below is paraphrased; the few quoted words are
|
|
4
|
+
marked. Socket's pages change often, so treat numbers as a snapshot.*
|
|
5
|
+
|
|
6
|
+
[Socket](https://socket.dev) is a well-funded supply-chain security company and
|
|
7
|
+
one of the clearest communicators in the field. These notes look at how it
|
|
8
|
+
explains itself, so Penthera can learn from the craft without copying the claims
|
|
9
|
+
or picking a fight. Penthera is a complement to Socket, not a rival: Socket
|
|
10
|
+
watches the registries from the cloud; Penthera checks your app and your machine
|
|
11
|
+
offline.
|
|
12
|
+
|
|
13
|
+
## 1. The headline promise
|
|
14
|
+
|
|
15
|
+
- The hero line is about securing software at "AI speed", with a sub-line that
|
|
16
|
+
promises to stop malicious packages before they reach your code
|
|
17
|
+
([home](https://socket.dev/)). The tab title frames it as blocking zero-day
|
|
18
|
+
supply-chain attacks.
|
|
19
|
+
- The core argument is one contrast, repeated on nearly every page: a CVE
|
|
20
|
+
database lists accidental vulnerabilities after disclosure, while a malicious
|
|
21
|
+
package is intentional and has to be stopped before install. Socket claims the
|
|
22
|
+
second half that CVE scanners miss
|
|
23
|
+
([features](https://socket.dev/features),
|
|
24
|
+
[supply-chain attack prevention](https://socket.dev/use-case/supply-chain-attack-prevention)).
|
|
25
|
+
- AI is the urgency: coding agents pull in dependencies faster than people can
|
|
26
|
+
review them, so the attack surface grows
|
|
27
|
+
([features](https://socket.dev/features), [Series C post](https://socket.dev/blog/series-c)).
|
|
28
|
+
- A speed claim backs the promise: malicious packages flagged within minutes of
|
|
29
|
+
publication ([home](https://socket.dev/)).
|
|
30
|
+
|
|
31
|
+
**Takeaway.** One sentence of promise, one contrast that explains why existing
|
|
32
|
+
tools are not enough, and one reason it matters now. Penthera's equivalent: one
|
|
33
|
+
promise (check, vet, keep watching, on your machine), one contrast (rules you can
|
|
34
|
+
read versus a verdict from a service), and the same "now" (AI writes the code and
|
|
35
|
+
picks the packages).
|
|
36
|
+
|
|
37
|
+
## 2. Who they sell to
|
|
38
|
+
|
|
39
|
+
- **Buyers are security leaders.** The case-study quotes come from a CISO
|
|
40
|
+
(Anthropic), a head of security (Vercel), senior security engineers (MetaMask,
|
|
41
|
+
Drata) ([customers](https://socket.dev/customers)).
|
|
42
|
+
- **Developers are the way in.** The free GitHub app, the CLI and the `sfw`
|
|
43
|
+
firewall are the self-serve entry points, and comparison pages carry a wall of
|
|
44
|
+
developer tweets ([vs Snyk](https://socket.dev/compare/socket-vs-snyk)).
|
|
45
|
+
- **AI-native companies** are named prominently: Anthropic, Cursor, Replit,
|
|
46
|
+
Vercel and others ([Series C post](https://socket.dev/blog/series-c)).
|
|
47
|
+
- **Credibility from the team**: the founders present themselves as open-source
|
|
48
|
+
maintainers whose packages are downloaded at very large scale
|
|
49
|
+
([FAQ](https://socket.dev/faq)).
|
|
50
|
+
- **Pricing** is per developer seat ([pricing](https://socket.dev/pricing)):
|
|
51
|
+
a free plan for one seat with 1,000 scans a month and a lot included (GitHub
|
|
52
|
+
app, AI analysis, MCP server, install firewall); Team at $25 a seat a month
|
|
53
|
+
with a 5-seat minimum (adds reachability); Business at $50 with a 20-seat
|
|
54
|
+
minimum (adds SBOM, SSO, AI-model and Actions scanning); Enterprise on quote
|
|
55
|
+
(adds self-hosting options, other SCMs, and SAST, secrets and container scanning
|
|
56
|
+
under "Socket Basics").
|
|
57
|
+
- **Open source**: public OSI-licensed projects can get the Business plan free
|
|
58
|
+
as of August 2026
|
|
59
|
+
([announcement](https://socket.dev/blog/free-business-plan-upgrades-for-open-source)).
|
|
60
|
+
The pricing page still mentions the older free Team offer.
|
|
61
|
+
|
|
62
|
+
**Takeaway.** Socket speaks to the person who signs off and lets the developer
|
|
63
|
+
install it. Penthera has no buyer. Its audiences are people doing the work with
|
|
64
|
+
no security team behind them: a founder before launch, a team adopting coding
|
|
65
|
+
agents, a maintainer, a small EU company, an agency. So Penthera's use-case pages
|
|
66
|
+
are organised by situation, not by job title.
|
|
67
|
+
|
|
68
|
+
## 3. How use cases and comparisons are structured
|
|
69
|
+
|
|
70
|
+
**Comparison pages** ([Snyk](https://socket.dev/compare/socket-vs-snyk),
|
|
71
|
+
[Dependabot](https://socket.dev/compare/socket-vs-dependabot),
|
|
72
|
+
[Semgrep](https://socket.dev/compare/socket-vs-semgrep)) share one template:
|
|
73
|
+
|
|
74
|
+
1. "Socket vs X" with a benefit subtitle.
|
|
75
|
+
2. Two paragraphs placing the competitor in the "known vulnerabilities only" box.
|
|
76
|
+
3. Install and contact-sales buttons.
|
|
77
|
+
4. A feature table of 8 or 9 rows with checks and dashes.
|
|
78
|
+
5. A second row of buttons, then a tweet wall, then a footer call to action.
|
|
79
|
+
|
|
80
|
+
They concede little. Snyk gets checks for known vulnerabilities, licence
|
|
81
|
+
enforcement and an API; Dependabot only for known vulnerabilities. Categories
|
|
82
|
+
where the competitor is stronger (SAST depth, containers, IaC, DAST) do not
|
|
83
|
+
appear. There are no prices, benchmarks or third-party sources in the tables.
|
|
84
|
+
|
|
85
|
+
**Use-case pages** ([open source](https://socket.dev/use-case/open-source-security),
|
|
86
|
+
[SCA](https://socket.dev/use-case/sca),
|
|
87
|
+
[supply-chain attack prevention](https://socket.dev/use-case/supply-chain-attack-prevention))
|
|
88
|
+
mix an SEO definition ("what is SCA"), a problem framing, a feature checklist and
|
|
89
|
+
a live feed of recently blocked packages. The feed is the most persuasive
|
|
90
|
+
element: it shows the product working today.
|
|
91
|
+
|
|
92
|
+
There is no standalone "Why Socket" page; it is a menu that groups the case
|
|
93
|
+
studies and comparisons. The closest page is
|
|
94
|
+
[features](https://socket.dev/features).
|
|
95
|
+
|
|
96
|
+
**Takeaway.** Copy the shape (one page per audience, one per alternative, a
|
|
97
|
+
table that is quick to scan), not the tone. Penthera's comparison pages say
|
|
98
|
+
"use together", name where the other tool goes further, link every claim to the
|
|
99
|
+
vendor's own docs, and carry a last-checked date. That honesty is the
|
|
100
|
+
differentiator Penthera can afford and a funded vendor often cannot.
|
|
101
|
+
|
|
102
|
+
## 4. How they use proof
|
|
103
|
+
|
|
104
|
+
- **Big numbers** on the home page: about 11.6 million commits secured a month, 1.5 million repositories, 27,000
|
|
105
|
+
organisations, 10,000 attacks blocked a week ([home](https://socket.dev/)).
|
|
106
|
+
The same metric differs across pages (risk signals: 70, 80 or 85; unique threat
|
|
107
|
+
detections: 26,000 on [features](https://socket.dev/features) versus 300,000 on
|
|
108
|
+
the home page).
|
|
109
|
+
- **Logos and case studies.** The strongest one, Anthropic, gives an outcome:
|
|
110
|
+
most dependency reviews automated and hours saved each week per engineer
|
|
111
|
+
([Anthropic](https://socket.dev/case-study/anthropic)). Vercel and Drata
|
|
112
|
+
describe workflow and hygiene rather than numbers
|
|
113
|
+
([Vercel](https://socket.dev/case-study/vercel), [Drata](https://socket.dev/case-study/drata)).
|
|
114
|
+
MetaMask's engineer says openly that some false positives are an acceptable
|
|
115
|
+
price for early warning ([MetaMask](https://socket.dev/case-study/metamask)).
|
|
116
|
+
The Replit story was not retrievable (HTTP 403); its index card is about
|
|
117
|
+
reducing false positives.
|
|
118
|
+
- **Funding and badges**: total raised, a $1 billion valuation, SOC 2 Type 2, a
|
|
119
|
+
Fortune list, and an OpenAI early-access programme
|
|
120
|
+
([home](https://socket.dev/), [Series C post](https://socket.dev/blog/series-c)).
|
|
121
|
+
- **Research as proof**: threat write-ups with timestamps showing when the AI
|
|
122
|
+
scanner flagged an attack, plus downloadable indicators
|
|
123
|
+
([Rust crates post](https://socket.dev/blog/popular-rust-crates-compromised)).
|
|
124
|
+
- **No accuracy numbers.** No false-positive rate for malware verdicts is
|
|
125
|
+
published; false-positive language appears only for reachability cutting CVE
|
|
126
|
+
noise.
|
|
127
|
+
|
|
128
|
+
**Takeaway.** Penthera has no logos, no funding and no usage telemetry (by
|
|
129
|
+
design, it has no way to count users). What it can show is what a reader can
|
|
130
|
+
check: benchmark precision and recall with every miss listed, rule and test
|
|
131
|
+
counts generated from the code, a cited methodology, an OpenSSF Scorecard, and
|
|
132
|
+
2FA-approved releases with provenance. That is the "By the numbers" block in the
|
|
133
|
+
README, refreshed by `npm run docs:numbers`.
|
|
134
|
+
|
|
135
|
+
## 5. Calls to action
|
|
136
|
+
|
|
137
|
+
- Every page pairs a free self-serve action (install the GitHub app) with a sales
|
|
138
|
+
action (book a demo or contact sales) ([home](https://socket.dev/), compare and
|
|
139
|
+
use-case pages).
|
|
140
|
+
- Product pages lead with the install command
|
|
141
|
+
([CLI](https://socket.dev/features/cli),
|
|
142
|
+
[firewall](https://socket.dev/features/firewall)); every blog post ends with a
|
|
143
|
+
free firewall card.
|
|
144
|
+
- An urgency line: a phone number for teams under active attack.
|
|
145
|
+
|
|
146
|
+
**Takeaway.** Penthera has no sales step, so its call to action is the command
|
|
147
|
+
itself. The README opens with three `npx` commands that each take under a
|
|
148
|
+
minute and need no account.
|
|
149
|
+
|
|
150
|
+
## 6. What they leave unsaid
|
|
151
|
+
|
|
152
|
+
| Topic | What Socket's pages say | Room for Penthera |
|
|
153
|
+
|---|---|---|
|
|
154
|
+
| Offline use | No offline or air-gapped mode documented. Even self-hosted firewall modes check packages against Socket's API ([firewall free](https://docs.socket.dev/docs/socket-firewall-free), [pricing](https://socket.dev/pricing)). Only manifests and lockfiles are sent, not source ([FAQ](https://socket.dev/faq)) | Everything runs locally; `--offline` limits traffic to the named target |
|
|
155
|
+
| Deterministic verdicts | Static analysis first, then an LLM stage, then human review before a package is labelled known malware ([AI alert](https://socket.dev/alerts/gptMalware)). No claim of reproducible results | Same input, same output, with the rule and `file:line` for each finding |
|
|
156
|
+
| App and runtime security | No DAST or live-URL testing; first-party SAST and secrets only on Enterprise | URL and repo scans, fix recipes, verification |
|
|
157
|
+
| AI tooling | Covers it as packages: an MCP server for package lookups ([MCP guide](https://docs.socket.dev/docs/guide-to-socket-mcp)), firewall ecosystems that include agent skills and models ([firewall](https://socket.dev/features/firewall)), research on malicious MCP servers ([labs](https://socket.dev/labs)). Nothing found that audits a repo's own agent config | `penthera agents`: CLAUDE.md, `.mcp.json`, hooks, permissions, plugins, rule files |
|
|
158
|
+
| EU compliance | SBOM export (CycloneDX, SPDX, OpenVEX) on Business and up; no NIS2 or CRA page found; compliance messaging is SOC 2 and Vanta-style integrations | NIS2 readiness, CRA Article 14 drafts, SBOM and AI-BOM, signable evidence, free |
|
|
159
|
+
|
|
160
|
+
Two cautions. Socket does cover parts of AI tooling, and says so; Penthera's docs
|
|
161
|
+
should not claim it does not. And the AI-versus-rules point should be made
|
|
162
|
+
calmly: Socket's AI scanner once flagged Penthera itself as malware because the
|
|
163
|
+
repository contains real test payloads. That is a fair example of the trade-off,
|
|
164
|
+
not a gotcha. AI stages catch novel attacks that no rule anticipated; rules
|
|
165
|
+
explain themselves and do not misread intent. Running both is reasonable.
|
|
166
|
+
|
|
167
|
+
## 7. What Penthera's docs take from this
|
|
168
|
+
|
|
169
|
+
1. **A three-command "Try it in 60 seconds" block** near the top of the README,
|
|
170
|
+
as the call to action.
|
|
171
|
+
2. **Use-case pages by situation**, each with the problem, what to run, real
|
|
172
|
+
example output, and what Penthera does not do
|
|
173
|
+
([docs/use-cases/](../use-cases/README.md)).
|
|
174
|
+
3. **Comparison pages framed as "use together"**, with factual tables, where the
|
|
175
|
+
other tool goes further, links to the vendor's docs, and a last-checked date
|
|
176
|
+
([docs/compare/](../compare/README.md)).
|
|
177
|
+
4. **Proof without logos**: a short "By the numbers" block in the README, every
|
|
178
|
+
number checkable and refreshable.
|
|
179
|
+
5. **A shorter README** that points to per-command pages instead of carrying
|
|
180
|
+
every flag.
|
|
181
|
+
|
|
182
|
+
Things deliberately not copied: inflated or inconsistent numbers, tweet walls,
|
|
183
|
+
competitor tables that only list the author's strengths, and urgency language.
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# Use cases
|
|
2
|
+
|
|
3
|
+
Each page starts from a situation, not a feature: the problem, what to run, what
|
|
4
|
+
the output looks like, and what Penthera does not do for you.
|
|
5
|
+
|
|
6
|
+
| You are | Page |
|
|
7
|
+
|---|---|
|
|
8
|
+
| A solo founder or vibecoder about to launch | [Before launch](solo-founder.md) |
|
|
9
|
+
| A team adopting Claude Code or Cursor | [The AI-tooling supply chain](ai-coding-teams.md) |
|
|
10
|
+
| An open-source maintainer | [For maintainers](open-source-maintainers.md) |
|
|
11
|
+
| An EU SME with NIS2 or CRA duties | [Evidence for NIS2 and the CRA](eu-sme-compliance.md) |
|
|
12
|
+
| An agency shipping client apps | [A repeatable handover check](agencies.md) |
|
|
13
|
+
|
|
14
|
+
Using another security tool already? See [how Penthera fits with it](../compare/README.md).
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
# A repeatable handover check: for agencies shipping client apps
|
|
2
|
+
|
|
3
|
+
## The problem
|
|
4
|
+
|
|
5
|
+
An agency ships many similar apps for clients who assume security was handled.
|
|
6
|
+
Each project has a different team, a different deadline and a launch date that
|
|
7
|
+
does not move. A security review by a person for every launch is too expensive,
|
|
8
|
+
and "we followed best practice" does not survive a client's procurement
|
|
9
|
+
questionnaire or an incident.
|
|
10
|
+
|
|
11
|
+
## What to run
|
|
12
|
+
|
|
13
|
+
The same three steps on every project, in CI or before handover:
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
npx penthera https://preview.client.example --repo . --profile standard \
|
|
17
|
+
--sarif reports/scan.sarif -o reports/scan.json
|
|
18
|
+
npx penthera deps --license-policy permissive # dependency capabilities and licences
|
|
19
|
+
npx penthera agents # the agent config left in the repo
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
At handover, give the client a report written for them and a bundle they can
|
|
23
|
+
keep:
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
npx penthera https://client.example --repo . --audience owner > security-summary.md
|
|
27
|
+
npx penthera https://client.example --repo . --audience auditor \
|
|
28
|
+
--evidence handover/2026-10-19 --sign-key ~/.ssh/agency_ed25519
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
Pin the Penthera version in CI so every project is checked by the same rules,
|
|
32
|
+
and use `--baseline` to show only what is new since the last scan.
|
|
33
|
+
|
|
34
|
+
## What you get
|
|
35
|
+
|
|
36
|
+
The owner report is in plain language. From Penthera's own mock target:
|
|
37
|
+
|
|
38
|
+
```markdown
|
|
39
|
+
# Security summary
|
|
40
|
+
|
|
41
|
+
## In short
|
|
42
|
+
|
|
43
|
+
Penthera checked http://localhost:8765 and found **2 serious problems** to fix
|
|
44
|
+
this week, 5 moderate, 2 minor, 2 notes. The serious ones are things an attacker
|
|
45
|
+
could use today.
|
|
46
|
+
|
|
47
|
+
## What to do first
|
|
48
|
+
|
|
49
|
+
1. **Harden authentication and access control** (involved, a developer can do this). ...
|
|
50
|
+
2. **Remove the exposed file or interface from production** (quick, a developer can do this). ...
|
|
51
|
+
3. **Add a Content-Security-Policy header** (moderate, a developer can do this). ...
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
The auditor version covers scope and method, every finding with its evidence and
|
|
55
|
+
confidence, the hosts contacted, and the probes that could not run. The evidence bundle hashes every file in a
|
|
56
|
+
signed manifest, so the client can check later that nothing was edited.
|
|
57
|
+
`--report-template` puts the same data into your own Markdown template.
|
|
58
|
+
[More on reports and evidence](../evidence.md).
|
|
59
|
+
|
|
60
|
+
## What it does not do
|
|
61
|
+
|
|
62
|
+
- It does not replace a penetration test where a contract or a regulator asks for
|
|
63
|
+
one. It makes that test cheaper, because the routine findings are already gone.
|
|
64
|
+
- It only scans what you point it at, with the client's permission. Get the scope
|
|
65
|
+
in writing.
|
|
66
|
+
- Fix recipes cover common JavaScript and TypeScript frameworks. Other stacks get
|
|
67
|
+
findings and guidance, not diffs.
|
|
68
|
+
- It does not monitor client production after handover yet. That is on the
|
|
69
|
+
[roadmap](../../ROADMAP.md).
|
|
70
|
+
|
|
71
|
+
[All use cases](README.md) · [Back to the README](../../README.md)
|