@topy-ai/maggie 0.7.55 → 0.7.57
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/README-zh-TW.md +7 -3
- package/README.md +42 -8
- package/bin/maggie.js +4 -0
- package/bundled-contracts/maggie-deployment/readiness-v1.schema.json +2 -1
- package/bundled-contracts/maggie-security/finding-example-v1.json +89 -0
- package/bundled-contracts/maggie-security/finding-v1.schema.json +63 -0
- package/bundled-contracts/maggie-security/findings-set-example-v1.json +148 -0
- package/bundled-contracts/maggie-security/findings-set-v1.schema.json +32 -0
- package/bundled-contracts/maggie-security/protect-plan-v1.schema.json +28 -0
- package/bundled-contracts/maggie-security/report-v1.schema.json +29 -0
- package/bundled-contracts/maggie-security/stack-example-v1.json +66 -0
- package/bundled-contracts/maggie-security/stack-upload-v1.schema.json +22 -0
- package/bundled-contracts/maggie-security/stack-v1.schema.json +37 -0
- package/bundled-contracts/maggie-security/tools-lock-v1.schema.json +36 -0
- package/bundled-skills/catalog.json +4 -0
- package/bundled-skills/maggie-security/SKILL.md +173 -0
- package/bundled-skills/maggie-security/agents/openai.yaml +4 -0
- package/bundled-skills/maggie-security/data/LICENSE-NOTICE.md +24 -0
- package/bundled-skills/maggie-security/data/asvs-map.json +209 -0
- package/bundled-skills/maggie-security/data/fail2ban/filter.d/maggie-wordpress.conf +6 -0
- package/bundled-skills/maggie-security/data/semgrep/LICENSE-NOTICE.md +5 -0
- package/bundled-skills/maggie-security/data/semgrep/VERSION +1 -0
- package/bundled-skills/maggie-security/data/semgrep/rules/dockerfile.yaml +14 -0
- package/bundled-skills/maggie-security/data/semgrep/rules/generic.yaml +26 -0
- package/bundled-skills/maggie-security/data/semgrep/rules/js.yaml +216 -0
- package/bundled-skills/maggie-security/data/semgrep/rules/php-debug-ok.yaml +17 -0
- package/bundled-skills/maggie-security/data/semgrep/rules/php-debug.yaml +17 -0
- package/bundled-skills/maggie-security/data/semgrep/rules/php.yaml +101 -0
- package/bundled-skills/maggie-security/data/semgrep/tests/dockerfile.dockerfile +10 -0
- package/bundled-skills/maggie-security/data/semgrep/tests/generic.astro +11 -0
- package/bundled-skills/maggie-security/data/semgrep/tests/generic.conf +11 -0
- package/bundled-skills/maggie-security/data/semgrep/tests/js.jsx +95 -0
- package/bundled-skills/maggie-security/data/semgrep/tests/php-debug-ok.php +5 -0
- package/bundled-skills/maggie-security/data/semgrep/tests/php-debug.php +3 -0
- package/bundled-skills/maggie-security/data/semgrep/tests/php.php +55 -0
- package/bundled-skills/maggie-security/evals/evals.json +97 -0
- package/bundled-skills/maggie-security/references/commands.md +125 -0
- package/bundled-skills/maggie-security/references/cve-response.md +24 -0
- package/bundled-skills/maggie-security/references/explaining-findings.md +57 -0
- package/bundled-skills/maggie-security/references/findings.md +39 -0
- package/bundled-skills/maggie-security/references/ownership-and-consent.md +29 -0
- package/bundled-skills/maggie-security/references/site-types.md +22 -0
- package/bundled-skills/maggie-security/references/tools-and-licences.md +16 -0
- package/bundled-skills/maggie-security/references/workflows.md +23 -0
- package/bundled-skills/maggie-security/registry/security-tools.registry.json +654 -0
- package/bundled-skills/maggie-security/routines.example.json +27 -0
- package/bundled-tools/clis/maggie_deployment_readiness.py +17 -2
- package/bundled-tools/clis/maggie_security.py +342 -0
- package/bundled-tools/clis/maggie_security_agent.py +326 -0
- package/bundled-tools/clis/maggie_security_code.py +650 -0
- package/bundled-tools/clis/maggie_security_core.py +1512 -0
- package/bundled-tools/clis/maggie_security_deps.py +560 -0
- package/bundled-tools/clis/maggie_security_health.py +415 -0
- package/bundled-tools/clis/maggie_security_host.py +511 -0
- package/bundled-tools/clis/maggie_security_hosted.py +115 -0
- package/bundled-tools/clis/maggie_security_intel.py +1294 -0
- package/bundled-tools/clis/maggie_security_inventory.py +1023 -0
- package/bundled-tools/clis/maggie_security_logs.py +777 -0
- package/bundled-tools/clis/maggie_security_mcp.py +484 -0
- package/bundled-tools/clis/maggie_security_mirror.py +122 -0
- package/bundled-tools/clis/maggie_security_protect.py +519 -0
- package/bundled-tools/clis/maggie_security_report.py +506 -0
- package/bundled-tools/clis/maggie_security_standards.py +214 -0
- package/bundled-tools/clis/maggie_security_versions.py +381 -0
- package/bundled-tools/clis/maggie_security_web.py +1247 -0
- package/bundled-tools/clis/security_data/eol-snapshot.json +1 -0
- package/bundled-tools/clis/security_data/gitleaks-rules.json +3812 -0
- package/bundled-tools/clis/security_data/maltrail-lists.json +1 -0
- package/bundled-tools/clis/security_data/public-suffix-icann.txt +7374 -0
- package/bundled-tools/clis/security_data/retire-extractors.json +695 -0
- package/bundled-tools/clis/security_data/sigma-web.json +6514 -0
- package/bundled-tools/clis/security_data/tools.lock.json +358 -0
- package/package.json +1 -1
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
# Commands
|
|
2
|
+
|
|
3
|
+
Every command takes the common flags: `--project PATH`, `--site ID`,
|
|
4
|
+
`--format json|sarif|md|text`, `--output FILE`, `--fail-on SEVERITY`, `--ci`,
|
|
5
|
+
`--offline`, `--since 24h`, `--max-items N`, `--no-ledger`, `--explain-egress`.
|
|
6
|
+
|
|
7
|
+
Exit codes: 0 ok · 1 findings at/above `--fail-on` · 2 usage · 3 degraded
|
|
8
|
+
(a source or tool did not answer) · 4 refused by policy · 5 scanner missing
|
|
9
|
+
or checksum mismatch.
|
|
10
|
+
|
|
11
|
+
## Housekeeping
|
|
12
|
+
|
|
13
|
+
| Command | What it does |
|
|
14
|
+
|---|---|
|
|
15
|
+
| `maggie security doctor [--fix]` | site type, domains, applicable checks, tools, feed freshness, consents, ledger counts; `--fix` writes `config.json` and the `.gitignore` entry |
|
|
16
|
+
| `maggie security tools list\|install\|verify [--tool NAME]` | pinned external scanners in `~/.cache/maggie/security-tools/`; refuses unpinned or mismatched binaries |
|
|
17
|
+
| `maggie security feeds status\|sync\|verify [--source ID]` | the feed cache under `.maggie/security/feeds/` |
|
|
18
|
+
| `maggie security ledger list\|show\|accept\|false-positive\|reopen\|compact` | finding status history; `accept` and `false-positive` need `--reason` |
|
|
19
|
+
| `maggie security consent grant\|revoke\|list --host ALIAS --level ssh-read` | per-host consent; granting is interactive only |
|
|
20
|
+
|
|
21
|
+
## Vulnerability intelligence
|
|
22
|
+
|
|
23
|
+
| Command | What it does | Sources contacted |
|
|
24
|
+
|---|---|---|
|
|
25
|
+
| `maggie security inventory` | builds `stack.json` from lockfiles, manifests, images, version files, JS bundles, WordPress and host evidence | none |
|
|
26
|
+
| `maggie security vuln-watch [--sources osv,node,wp,software,cvelistv5,kev,epss]` | matches the stack against every source | api.osv.dev, raw.githubusercontent.com, www.wpvulnerability.net, api.first.org |
|
|
27
|
+
| `maggie security osv-query --purl … \| --ecosystem --name --version \| --id … \| --stack` | one package, one advisory, or the whole stack | api.osv.dev |
|
|
28
|
+
| `maggie security wp-check` | WordPress core, plugins, themes; PHP/web server/database versions | www.wpvulnerability.net |
|
|
29
|
+
| `maggie security eol-watch [--product php=8.1]` | end of life and patch-behind for runtimes, databases, servers, distros, frameworks | endoflife.date (snapshot offline) |
|
|
30
|
+
| `maggie security node-check [--node-version 20.11.1]` | Node.js core advisories | raw.githubusercontent.com |
|
|
31
|
+
| `maggie security advisory --cve ID --component php \| --finding msf_…` | writes a `runtime-inventory --advisory` file | raw.githubusercontent.com, endoflife.date |
|
|
32
|
+
|
|
33
|
+
`--explain-egress` on any command prints the hosts it may contact. Only
|
|
34
|
+
package names and versions are sent to OSV; lockfiles, code, logs and
|
|
35
|
+
findings never leave the machine.
|
|
36
|
+
|
|
37
|
+
## Deploy gate
|
|
38
|
+
|
|
39
|
+
| Command | What it does | Sources contacted |
|
|
40
|
+
|---|---|---|
|
|
41
|
+
| `maggie security deps [--engine auto\|osv-scanner\|native] [--lockfiles-only\|--bundles-only] [--include-dev] [--ci]` | every lockfile ecosystem plus JavaScript copied into the site (retire.js repository); the pinned osv-scanner when installed, else the native OSV engine; `--offline` matches against `.maggie/security/db/osv` | api.osv.dev, raw.githubusercontent.com |
|
|
42
|
+
| `maggie security secrets [--scope git,tree,dist] [--engine auto\|gitleaks\|native] [--baseline FILE\|--write-baseline FILE]` | keys and passwords in git history, project files and build output, plus `.env` values copied into the build; gitleaks' 222 rules (MIT) and Maggie's; values never shown or stored | none |
|
|
43
|
+
| `maggie security report --kind gate --output FILE` | gate decision (block / warn / pass) for `maggie deployment readiness --security-report FILE` | none |
|
|
44
|
+
| `maggie security feeds mirror --dir DIR [--to-project]` | offline copy of every feed and the OSV ecosystem databases; point `MAGGIE_SECURITY_MIRROR` at it | every feed host |
|
|
45
|
+
|
|
46
|
+
## Web surface (verified domains only)
|
|
47
|
+
|
|
48
|
+
| Command | What it does | Contacted |
|
|
49
|
+
|---|---|---|
|
|
50
|
+
| `maggie security domain-verify start\|check\|status\|revoke --domain D [--method dns\|file]` | proves control of the registrable domain (TXT seen by the system resolver **and** DNS-over-HTTPS) or one host (file); valid 90 days, re-checked weekly | system resolver, cloudflare-dns.com, the site |
|
|
51
|
+
| `maggie security headers --url U [--paths / /login] [--serving auto\|nginx\|apache\|cloudflare\|headers-file\|astro\|next\|php]` | grades security headers and cookies per path (ASVS 5.0 ids), plain-HTTP redirect, fix snippets for the serving layer; a new CSP is always suggested as Report-Only first | the site |
|
|
52
|
+
| `maggie security tls --host H [--engine auto\|testssl\|native] [--ip ORIGIN]` | certificate trust and expiry, TLS 1.0/1.1 still accepted, TLS 1.3 missing; testssl.sh (GPL, installed by the person) when present | the site |
|
|
53
|
+
| `maggie security web-scan --url U [--profile safe\|full-safe]` | httpx fingerprint, then nuclei with the safe profile (no intrusive, fuzz, DoS, brute-force, OAST templates; ≤ 10 req/s; one scan per domain at a time) | the site |
|
|
54
|
+
| `maggie security zap-baseline --url U` | weekly passive ZAP baseline in Docker; header rules skipped (headers covers them) | the site |
|
|
55
|
+
|
|
56
|
+
## Public check (sites you do NOT control — passive only)
|
|
57
|
+
|
|
58
|
+
`public-check` is the one web command that does not need domain verification,
|
|
59
|
+
because it only does what any visitor already does: one GET of the home page, a
|
|
60
|
+
TLS handshake, and public DNS. It never probes paths, never submits anything,
|
|
61
|
+
and never runs an active scanner. Use it to spot a visible problem on someone
|
|
62
|
+
else's site and tell them. It is interactive-only (refused under `--ci` or in a
|
|
63
|
+
routine) and never writes to the ledger. `web-scan`, `zap-baseline` and the host
|
|
64
|
+
checks stay verified-only — do not run them against a site you do not control.
|
|
65
|
+
|
|
66
|
+
| Command | What it does | Contacted |
|
|
67
|
+
|---|---|---|
|
|
68
|
+
| `maggie security public-check --url U` / `--domain D` (repeatable) / `--domains FILE` `[--outreach DIR] [--rate N] [--max-sites N]` | per site: security headers + cookies, TLS certificate and protocols, versions disclosed on the home page (`generator` meta, `Server`/`X-Powered-By`, JS libraries) matched to known CVEs (OSV, WPVulnerability, KEV, EPSS), missing/weak SPF and DMARC, and missing `security.txt`. `--outreach` writes a disclosure-ready note per domain (what is visible, no exploit detail). | the site, system resolver, cloudflare-dns.com, api.osv.dev, wpvulnerability.net, KEV, api.first.org |
|
|
69
|
+
|
|
70
|
+
## Code
|
|
71
|
+
|
|
72
|
+
| Command | What it does |
|
|
73
|
+
|---|---|
|
|
74
|
+
| `maggie security code-scan [--changed-since REF] [--rules maggie\|DIR] [--baseline FILE\|--write-baseline FILE]` | semgrep (LGPL, installed by the person, `--metrics=off`) with Maggie's 22-rule pack for Astro, React/Next, Node, PHP/WordPress, Dockerfile, nginx, plus native checks for root containers and served dotfiles; registry rules are refused |
|
|
75
|
+
|
|
76
|
+
## Logs (read where they are; never uploaded)
|
|
77
|
+
|
|
78
|
+
| Command | What it does |
|
|
79
|
+
|---|---|
|
|
80
|
+
| `maggie security logs-traffic --file access.log* [--since 7d] [--exclude-ip CIDR]` | requests, error rate, top pages/404s/addresses, crawler share, change against the last run; flags 5xx bursts and one address dominating |
|
|
81
|
+
| `maggie security logs-sigma --file access.log [--rules web,proxy,emerging] [--min-level medium]` | 143 SigmaHQ web rules (DRL 1.1) on the log; attempts unless a webshell or secret file was served with content or an exploit for a CVE the site has got a normal response (then `compromise-indicator`, p0); `--list-rules` |
|
|
82
|
+
| `maggie security logs-ioc --file access.log [--feeds blocklist-de,…]` | maltrail mass-scanner and user-agent lists (MIT); extra IP feeds only when you choose them after reading their terms; scores 0–100 |
|
|
83
|
+
| `maggie security logs-remote --ssh web1=user@host [--pattern /xmlrpc.php]` | summary computed on the server by an inline awk program; nothing is written there and no log line comes back |
|
|
84
|
+
|
|
85
|
+
Formats: nginx/Apache combined and vcombined, Caddy JSON, Cloudflare Logpush JSON; `.gz` files are fine.
|
|
86
|
+
|
|
87
|
+
## Hosts (read-only unless stated)
|
|
88
|
+
|
|
89
|
+
| Command | What it does | Consent |
|
|
90
|
+
|---|---|---|
|
|
91
|
+
| `maggie security host-quick --ssh web1=user@host \| --evidence FILE \| --print-collector` | SSH, firewall, automatic updates, fail2ban/CrowdSec and port alignment, databases listening publicly, Docker bypassing UFW, SUID, sudo logging, disk/memory; checks ported from vps-audit (MIT) | ssh-read |
|
|
92
|
+
| `maggie security host-nginx-config --ssh web1=user@host \| --evidence FILE` | nginx -T and php -i rules: hidden files, PHP in uploads, PATH_INFO, old TLS/weak ciphers, HSTS, add_header inheritance, WordPress login limits, xmlrpc, key permissions | ssh-read |
|
|
93
|
+
| `maggie security host-audit --ssh web1=user@host \| --evidence report.dat` | lynis (GPL, external) uploaded to a private /tmp folder under the host lock, removed afterwards (verified); hardening index and warnings | ssh-temp-write |
|
|
94
|
+
| `maggie security incident start\|log\|close\|show\|list` | timeline for a CVE response; `report --kind incident` prints it | none |
|
|
95
|
+
|
|
96
|
+
## Protect and assure
|
|
97
|
+
|
|
98
|
+
| Command | What it does |
|
|
99
|
+
|---|---|
|
|
100
|
+
| `maggie security protect-plan [create\|validate\|verify] --host web1 [--engine auto\|crowdsec\|fail2ban\|cloudflare] [--allow-ip IP] [--behind-cloudflare] [--log access.log]` | plan only: host lock first and last, a rollback per step, CrowdSec sharing off unless `--capi` (interactive), fail2ban WordPress filter tested on your log; `validate` rejects piped installers, unlisted downloads, missing rollbacks; `verify` checks the result read-only |
|
|
101
|
+
| `maggie security uptime-init\|uptime-deploy\|uptime-status\|uptime-push` | Gatus config for verified domains (status, latency, certificate and domain expiry, brand text, DNS, redirect) and security-job heartbeats; a deploy plan (127.0.0.1, digest-pinned image); status findings; heartbeat pushes with short codes only |
|
|
102
|
+
| `maggie security checklist [--level 1\|2\|3] [--profile …]` | OWASP ASVS 5.0 (read from OWASP at run time, CC BY-SA) filled from findings: pass only with positive coverage |
|
|
103
|
+
| `maggie security threat-model [--include-findings]` | OWASP Threat Dragon v2 STRIDE draft |
|
|
104
|
+
| `maggie security waf-replay --log access.log [--paranoia 2] [--threshold 5] [--exclude-bots]` | replays the log through Coraza + OWASP CRS v4 offline (helper `maggie-waf-replay`); share of real visitors each paranoia level would block, rules needing exclusions; feeds `protect-plan --replay-report` |
|
|
105
|
+
| `maggie security sbom [--engine native\|syft] [--image REF]` | CycloneDX 1.5 SBOM |
|
|
106
|
+
| `maggie security image REF` | trivy (vulns, secrets without values, misconfig, EOL base) + dockle |
|
|
107
|
+
| `maggie security preinstall PKG[@V] [--threshold strict]` | npm package vetting: age, version age, install scripts, typosquats, OSV MAL-/vulns, Scorecard; never installs |
|
|
108
|
+
| `maggie security exposure-check [--root DIR] [--deep] [--catalog-dir DIR]` | malicious packages already installed (OSV MAL- and incident catalogs) |
|
|
109
|
+
| `maggie security skills-scan PATH [--kind mcp-registry] [--max-risk 50]` | SkillSpector (installed by you, `--no-llm` forced) |
|
|
110
|
+
| `maggie security mcp-self-check [--registry FILE --mcp-tools FILE --server-config FILE --previous FILE]` | OWASP MCP checks MCP-01..MCP-15 |
|
|
111
|
+
| `maggie security github-alerts --from-file alerts.json --repo OWNER/NAME` | Dependabot, code-scanning, secret-scanning alerts as findings (direct mode uses your own `GITHUB_TOKEN`) |
|
|
112
|
+
|
|
113
|
+
## Hosted watch (CMO.so)
|
|
114
|
+
|
|
115
|
+
| Command | What it does |
|
|
116
|
+
|---|---|
|
|
117
|
+
| `maggie security inventory --export-upload FILE --workspace example.com` | names and versions of packages, runtimes and WordPress items only — no paths, hosts, lockfiles, logs or secrets |
|
|
118
|
+
| `maggie security hosted-job --stack-upload FILE --state-dir DIR --workspace example.com` | the server job: daily watch on the upload with per-workspace caps; returns a `report_save` payload only when something is new |
|
|
119
|
+
|
|
120
|
+
## Reports and agents
|
|
121
|
+
|
|
122
|
+
| Command | What it does |
|
|
123
|
+
|---|---|
|
|
124
|
+
| `maggie security report --kind weekly\|daily_ops\|incident\|gate [--audience owner\|technical] [--save]` | Markdown + JSON report from the latest runs; `--save` writes the `report_save` payload |
|
|
125
|
+
| `maggie security mcp [--tools p0\|all] [--print-config claude\|codex]` | local stdio MCP server |
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# CVE response (W2)
|
|
2
|
+
|
|
3
|
+
For a CVE in a runtime, database, web server or the OS. Steps 3–5 need the
|
|
4
|
+
person; a routine never goes past step 2.
|
|
5
|
+
|
|
6
|
+
1. `maggie security advisory --cve CVE-ID --component php` (or `--finding msf_…`)
|
|
7
|
+
→ `.maggie/security/advisories/CVE-ID-php.json`:
|
|
8
|
+
`{"id", "component", "fixed": {"8.1": "8.1.29"}, "unsupportedLines": ["7.4"]}`.
|
|
9
|
+
2. `maggie deployment runtime-inventory --ssh deploy@HOST --advisory FILE`
|
|
10
|
+
→ affected sites and a migration plan per site. (Needs `ssh-read` consent.)
|
|
11
|
+
Components other than PHP are written with `"planner": "manual"`: describe
|
|
12
|
+
the upgrade yourself from the fixed versions.
|
|
13
|
+
3. Show the plan: what changes, expected downtime, how to roll back. **Wait for approval.**
|
|
14
|
+
4. `maggie deployment host-lock acquire --host HOST --session S --purpose "CVE-ID response"`.
|
|
15
|
+
If `host-lock status` shows recent changes by someone else, stop and ask.
|
|
16
|
+
5. The person runs the plan, or you run it in this interactive session after
|
|
17
|
+
they approved that exact plan.
|
|
18
|
+
6. Re-run step 2: it must show 0 affected sites.
|
|
19
|
+
7. `maggie security vuln-watch` — the ledger marks the finding fixed only from a complete run.
|
|
20
|
+
8. `maggie deployment host-lock release …`.
|
|
21
|
+
9. `maggie security report --kind incident --save` with the timeline.
|
|
22
|
+
|
|
23
|
+
No fix available: the plan is mitigation only (disable the feature, block the
|
|
24
|
+
path, isolate the service) and the report says "no fix yet".
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# Explaining findings
|
|
2
|
+
|
|
3
|
+
Four parts, plain words, one action per finding:
|
|
4
|
+
|
|
5
|
+
> **What we found:** … **Why it matters:** … **What to do:** … **How urgent:** …
|
|
6
|
+
|
|
7
|
+
Urgency words: p0 today · p1 this week · p2 this month · p3 when convenient · p4 for information.
|
|
8
|
+
No CVSS vectors, purls or rule ids for site owners; keep them for developers.
|
|
9
|
+
Name components the way the owner sees them (the plugin's name in WordPress,
|
|
10
|
+
"your database (MySQL 5.7)", "the server's operating system (Ubuntu 20.04)").
|
|
11
|
+
|
|
12
|
+
## vulnerability
|
|
13
|
+
|
|
14
|
+
> **What we found:** Your site uses Next.js 14.2.10.
|
|
15
|
+
> **Why it matters:** A flaw in this version lets visitors skip login checks. Attackers are using it now.
|
|
16
|
+
> **What to do:** Update Next.js to 14.2.25, rebuild and redeploy.
|
|
17
|
+
> **How urgent:** Today.
|
|
18
|
+
|
|
19
|
+
When there is no fix: say "no fixed version yet", list what reduces the risk
|
|
20
|
+
(turn the feature off, block the path, replace the package) and never invent
|
|
21
|
+
a version.
|
|
22
|
+
|
|
23
|
+
## vulnerability on a runtime, database or server
|
|
24
|
+
|
|
25
|
+
> **What we found:** The server web1 runs PHP 7.4.33.
|
|
26
|
+
> **Why it matters:** PHP 7.4 has a known flaw that attackers use to run commands, and it gets no more fixes.
|
|
27
|
+
> **What to do:** Move the site to PHP 8.3. I can prepare the plan; you approve it before anything changes.
|
|
28
|
+
> **How urgent:** Today.
|
|
29
|
+
|
|
30
|
+
## eol
|
|
31
|
+
|
|
32
|
+
> **What we found:** Your database is PostgreSQL 12.
|
|
33
|
+
> **Why it matters:** It stopped getting security fixes on 2024-11-21, so new flaws will not be fixed.
|
|
34
|
+
> **What to do:** Plan an upgrade to PostgreSQL 17 or 18.
|
|
35
|
+
> **How urgent:** This week to plan; schedule the move this month.
|
|
36
|
+
|
|
37
|
+
Patch-behind (`info`): "PostgreSQL 16.2 is behind the latest 16.x update (16.6). Apply it at the next maintenance window."
|
|
38
|
+
|
|
39
|
+
## malicious-package
|
|
40
|
+
|
|
41
|
+
> **What we found:** The package `x` in your project is known to be malicious.
|
|
42
|
+
> **Why it matters:** It was published to steal data or keys.
|
|
43
|
+
> **What to do:** Remove it now, rotate any keys on machines that installed it, and check the lockfile for how it got in.
|
|
44
|
+
> **How urgent:** Today.
|
|
45
|
+
|
|
46
|
+
## secret
|
|
47
|
+
|
|
48
|
+
> **What we found:** An API key in `src/config.js` line 2 (`mgfx…5nMq`).
|
|
49
|
+
> **Why it matters:** Anyone who can read that file can use the key.
|
|
50
|
+
> **What to do:** Revoke the key with the provider first, then remove it from the code and history.
|
|
51
|
+
> **How urgent:** Today.
|
|
52
|
+
|
|
53
|
+
Never show the value; the preview (first 4 + last 4) is all there is.
|
|
54
|
+
|
|
55
|
+
## possible matches
|
|
56
|
+
|
|
57
|
+
> A new advisory names PostgreSQL but gives no version range. Worth a look: check whether 13.11 is listed on the vendor page.
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# Findings, priority and the ledger
|
|
2
|
+
|
|
3
|
+
A finding (`contracts/maggie-security/finding-v1.schema.json`) names the
|
|
4
|
+
site, the component and version, the fixed version, whether it is exploited
|
|
5
|
+
(`kev`), how likely exploitation is (`epss`), the evidence and the fix.
|
|
6
|
+
|
|
7
|
+
## Priority (first match wins)
|
|
8
|
+
|
|
9
|
+
| Priority | When |
|
|
10
|
+
|---|---|
|
|
11
|
+
| p0 | on CISA KEV with a confirmed/likely match on an internet-facing component; a confirmed secret in a public file; a compromise indicator |
|
|
12
|
+
| p1 | critical; high with EPSS ≥ 0.1; an internet-facing runtime past end of life |
|
|
13
|
+
| p2 | high; medium with a fix on a direct dependency; end of life within 30 days |
|
|
14
|
+
| p3 | medium/low; end of life within 90 days; hardening |
|
|
15
|
+
| p4 | information; `possible` matches with no corroboration; dev-only |
|
|
16
|
+
|
|
17
|
+
Dev-only scope lowers one step except for secrets.
|
|
18
|
+
|
|
19
|
+
## Confidence
|
|
20
|
+
|
|
21
|
+
- `confirmed`: exact version or range match from a package database.
|
|
22
|
+
- `likely`: a CVE record's version range for a product name in the stack.
|
|
23
|
+
- `possible`: the product is named but no range applies — "worth a look".
|
|
24
|
+
|
|
25
|
+
## Status and the ledger
|
|
26
|
+
|
|
27
|
+
`.maggie/security/ledger.jsonl` keeps one line per event. A finding is
|
|
28
|
+
`new` the first time, `open` after that, `fixed` only when a complete run
|
|
29
|
+
covered the same target and it was gone. A degraded run never marks
|
|
30
|
+
anything fixed. `accepted-risk` expires (default 90 days) and comes back
|
|
31
|
+
`open`; `false-positive` stays until reopened. A new KEV listing or a
|
|
32
|
+
higher severity re-reports an open finding as `new` with `change: escalated`.
|
|
33
|
+
|
|
34
|
+
Only mark a finding when the person says so:
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
maggie security ledger accept --id msf_… --reason "dev-only tool, not deployed" --until 2027-01-31
|
|
38
|
+
maggie security ledger false-positive --id msf_… --reason "plugin folder renamed, different plugin"
|
|
39
|
+
```
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# Ownership, consent and what leaves the machine
|
|
2
|
+
|
|
3
|
+
| Level | Examples | How granted |
|
|
4
|
+
|---|---|---|
|
|
5
|
+
| read-local | lockfiles, logs on disk | implicit |
|
|
6
|
+
| read-public | public feeds, OSV queries with package names | implicit; `--offline` refuses |
|
|
7
|
+
| scan-owned | headers/TLS/web scans of a verified domain | `maggie security domain-verify start` → the person adds the TXT record → `check` |
|
|
8
|
+
| ssh-read | `inventory --ssh` | `maggie security consent grant --host web1 --level ssh-read`, typed by the person |
|
|
9
|
+
| host-change | installing or editing anything on a server | never by a security command |
|
|
10
|
+
|
|
11
|
+
Sent off the machine: package names and versions (OSV), plugin slugs and
|
|
12
|
+
versions (WPVulnerability), CVE ids (FIRST EPSS). Never: lockfile contents,
|
|
13
|
+
code, logs, host evidence, secrets, findings. `--explain-egress` lists the
|
|
14
|
+
hosts per command; `--offline` makes no connections and uses the cache and
|
|
15
|
+
packaged snapshots.
|
|
16
|
+
|
|
17
|
+
## Verifying a domain
|
|
18
|
+
|
|
19
|
+
1. `maggie security domain-verify start --domain example.com` prints a TXT
|
|
20
|
+
record: name `_maggie-security.example.com`, value
|
|
21
|
+
`maggie-site-verification=<token>`. The token is shown once; only its hash is kept.
|
|
22
|
+
2. The person adds it at their DNS provider.
|
|
23
|
+
3. `maggie security domain-verify check --domain example.com` passes when the
|
|
24
|
+
system resolver and a public DNS-over-HTTPS resolver both see it. The record
|
|
25
|
+
covers the registrable domain and its subdomains for 90 days and is
|
|
26
|
+
re-checked every 7 days; removing the TXT record ends scanning within a week.
|
|
27
|
+
|
|
28
|
+
`--method file` instead serves the token at
|
|
29
|
+
`https://host/.well-known/maggie-security-verification.txt` and covers that host only.
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# Site types and stacks
|
|
2
|
+
|
|
3
|
+
`maggie security doctor` detects the site type; `inventory` reads whatever
|
|
4
|
+
is present, so mixed projects work.
|
|
5
|
+
|
|
6
|
+
| Stack | Inventory reads | Matched by |
|
|
7
|
+
|---|---|---|
|
|
8
|
+
| JavaScript/TypeScript | package-lock, npm-shrinkwrap, pnpm-lock, yarn.lock, bun.lock, package.json pins, shipped `*.js` bundles | OSV (npm) |
|
|
9
|
+
| PHP | composer.lock; PHP version from hosts/images | OSV (Packagist); WPVulnerability (php); endoflife.date |
|
|
10
|
+
| Python | requirements*.txt pins, Pipfile.lock, poetry.lock, uv.lock, pdm.lock, `.python-version`, runtime.txt | OSV (PyPI); endoflife.date |
|
|
11
|
+
| Java/Kotlin | pom.xml (properties resolved), gradle.lockfile, Spring Boot parent | OSV (Maven); endoflife.date (Java, Spring Boot, Tomcat) |
|
|
12
|
+
| Go | go.mod (+ `go` directive → Go standard library) | OSV (Go, Go/stdlib); endoflife.date |
|
|
13
|
+
| Ruby | Gemfile.lock (+ RUBY VERSION) | OSV (RubyGems); endoflife.date |
|
|
14
|
+
| Rust | Cargo.lock | OSV (crates.io) |
|
|
15
|
+
| .NET | packages.lock.json, *.csproj, Directory.Packages.props, global.json | OSV (NuGet); endoflife.date |
|
|
16
|
+
| WordPress | core, plugins, themes from files (+ `wp plugin list --format=json` for active state) | WPVulnerability; endoflife.date |
|
|
17
|
+
| Databases and servers | Dockerfile/compose images; host collector (`mysqld`, `postgres`, `redis-server`, `mongod`, `nginx`, `apache2`, `memcached`, `openssl`, `java`…) | WPVulnerability (php, nginx, apache, mysql, mariadb, redis, memcached, sqlite), CVE delta product match, endoflife.date |
|
|
18
|
+
| Linux | `/etc/os-release`, dpkg/rpm/apk package lists from the host collector | OSV (Debian, Ubuntu, Alpine, Rocky, Alma); endoflife.date |
|
|
19
|
+
|
|
20
|
+
Red Hat package lists are inventoried but OSV matching for RHEL needs
|
|
21
|
+
repository-specific ecosystem names and is not done yet; RHEL hosts still get
|
|
22
|
+
end-of-life and CVE product checks.
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# Tools and licences
|
|
2
|
+
|
|
3
|
+
Scanners are pinned in `tools/clis/security_data/tools.lock.json` with
|
|
4
|
+
version, licence class and sha256 per platform. `maggie security tools
|
|
5
|
+
install --tool NAME` downloads to `~/.cache/maggie/security-tools/`, checks
|
|
6
|
+
the sha256 and never uses sudo. The runner refuses a changed binary (exit 5)
|
|
7
|
+
and forbidden flags such as telemetry or cloud upload (exit 4), and adds the
|
|
8
|
+
required ones (for example nuclei `-ni -duc`).
|
|
9
|
+
|
|
10
|
+
| Class | Licences | Rule |
|
|
11
|
+
|---|---|---|
|
|
12
|
+
| bundle-ok | MIT, Apache-2.0, BSD, MPL-2.0 | may be called and redistributed with notices |
|
|
13
|
+
| external-only | GPL, LGPL | installed by the person from upstream; called as a separate process |
|
|
14
|
+
| reference-only | AGPL, BSL, ELv2 | design reference; not run by Maggie |
|
|
15
|
+
|
|
16
|
+
Packaged data and its attribution: [data/LICENSE-NOTICE.md](../data/LICENSE-NOTICE.md).
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# Workflows
|
|
2
|
+
|
|
3
|
+
## W1 Daily watch
|
|
4
|
+
|
|
5
|
+
```bash
|
|
6
|
+
maggie security inventory # when lockfiles, Dockerfiles or host evidence changed
|
|
7
|
+
maggie security vuln-watch # OSV, Node core, WPVulnerability, CVE delta, KEV, EPSS
|
|
8
|
+
maggie security eol-watch # end of life and patch-behind
|
|
9
|
+
maggie security report --kind daily_ops --save
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
- Notify only for `status: new` at p0/p1, or an `escalated` finding.
|
|
13
|
+
- `p0`/`p1` findings on a runtime, database, server or OS also write
|
|
14
|
+
`.maggie/security/advisories/<CVE>-<component>.json` for W2.
|
|
15
|
+
- A degraded source is named in the report; nothing is marked fixed from it.
|
|
16
|
+
|
|
17
|
+
Scheduling: off the hour (06:17), after the server's own jobs; check with
|
|
18
|
+
`maggie ops routines-check routines.json`. Example: `routines.example.json`
|
|
19
|
+
in this folder.
|
|
20
|
+
|
|
21
|
+
## W2 CVE response
|
|
22
|
+
|
|
23
|
+
See [CVE response](cve-response.md).
|