phpwarden 2.0.3__tar.gz → 2.1.1__tar.gz
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.
- {phpwarden-2.0.3 → phpwarden-2.1.1}/PKG-INFO +32 -7
- {phpwarden-2.0.3 → phpwarden-2.1.1}/README.md +31 -6
- {phpwarden-2.0.3 → phpwarden-2.1.1}/pyproject.toml +1 -1
- {phpwarden-2.0.3 → phpwarden-2.1.1}/src/phpwarden/__init__.py +1 -1
- {phpwarden-2.0.3 → phpwarden-2.1.1}/src/phpwarden/cli.py +41 -0
- {phpwarden-2.0.3 → phpwarden-2.1.1}/src/phpwarden/data/php-cve-feed.json +19978 -19692
- phpwarden-2.1.1/src/phpwarden/integrity.py +254 -0
- {phpwarden-2.0.3 → phpwarden-2.1.1}/src/phpwarden.egg-info/PKG-INFO +32 -7
- {phpwarden-2.0.3 → phpwarden-2.1.1}/src/phpwarden.egg-info/SOURCES.txt +7 -0
- {phpwarden-2.0.3 → phpwarden-2.1.1}/tests/test_advisories.py +123 -2
- phpwarden-2.1.1/tests/test_agency.py +321 -0
- phpwarden-2.1.1/tests/test_business_metrics.py +45 -0
- phpwarden-2.1.1/tests/test_integrity.py +109 -0
- phpwarden-2.1.1/tests/test_kev_gaps.py +23 -0
- phpwarden-2.1.1/tests/test_livefeed.py +76 -0
- phpwarden-2.1.1/tests/test_store_connections.py +40 -0
- {phpwarden-2.0.3 → phpwarden-2.1.1}/tests/test_wordpress_and_report.py +2 -1
- {phpwarden-2.0.3 → phpwarden-2.1.1}/LICENSE +0 -0
- {phpwarden-2.0.3 → phpwarden-2.1.1}/setup.cfg +0 -0
- {phpwarden-2.0.3 → phpwarden-2.1.1}/src/phpwarden/deps.py +0 -0
- {phpwarden-2.0.3 → phpwarden-2.1.1}/src/phpwarden/detect.py +0 -0
- {phpwarden-2.0.3 → phpwarden-2.1.1}/src/phpwarden/engine.py +0 -0
- {phpwarden-2.0.3 → phpwarden-2.1.1}/src/phpwarden/env.py +0 -0
- {phpwarden-2.0.3 → phpwarden-2.1.1}/src/phpwarden/feed.py +0 -0
- {phpwarden-2.0.3 → phpwarden-2.1.1}/src/phpwarden/guard.py +0 -0
- {phpwarden-2.0.3 → phpwarden-2.1.1}/src/phpwarden/report.py +0 -0
- {phpwarden-2.0.3 → phpwarden-2.1.1}/src/phpwarden/rules.py +0 -0
- {phpwarden-2.0.3 → phpwarden-2.1.1}/src/phpwarden/version.py +0 -0
- {phpwarden-2.0.3 → phpwarden-2.1.1}/src/phpwarden/vulndb.py +0 -0
- {phpwarden-2.0.3 → phpwarden-2.1.1}/src/phpwarden/wordpress.py +0 -0
- {phpwarden-2.0.3 → phpwarden-2.1.1}/src/phpwarden.egg-info/dependency_links.txt +0 -0
- {phpwarden-2.0.3 → phpwarden-2.1.1}/src/phpwarden.egg-info/entry_points.txt +0 -0
- {phpwarden-2.0.3 → phpwarden-2.1.1}/src/phpwarden.egg-info/top_level.txt +0 -0
- {phpwarden-2.0.3 → phpwarden-2.1.1}/tests/test_accounts.py +0 -0
- {phpwarden-2.0.3 → phpwarden-2.1.1}/tests/test_assignment.py +0 -0
- {phpwarden-2.0.3 → phpwarden-2.1.1}/tests/test_audit.py +0 -0
- {phpwarden-2.0.3 → phpwarden-2.1.1}/tests/test_billing.py +0 -0
- {phpwarden-2.0.3 → phpwarden-2.1.1}/tests/test_cli_edges.py +0 -0
- {phpwarden-2.0.3 → phpwarden-2.1.1}/tests/test_connect_flow.py +0 -0
- {phpwarden-2.0.3 → phpwarden-2.1.1}/tests/test_dashboard_states.py +0 -0
- {phpwarden-2.0.3 → phpwarden-2.1.1}/tests/test_deps_and_rules.py +0 -0
- {phpwarden-2.0.3 → phpwarden-2.1.1}/tests/test_detection_validation.py +0 -0
- {phpwarden-2.0.3 → phpwarden-2.1.1}/tests/test_developer.py +0 -0
- {phpwarden-2.0.3 → phpwarden-2.1.1}/tests/test_discussion.py +0 -0
- {phpwarden-2.0.3 → phpwarden-2.1.1}/tests/test_e2e_readiness.py +0 -0
- {phpwarden-2.0.3 → phpwarden-2.1.1}/tests/test_email.py +0 -0
- {phpwarden-2.0.3 → phpwarden-2.1.1}/tests/test_engine.py +0 -0
- {phpwarden-2.0.3 → phpwarden-2.1.1}/tests/test_engine_feed.py +0 -0
- {phpwarden-2.0.3 → phpwarden-2.1.1}/tests/test_feed_license.py +0 -0
- {phpwarden-2.0.3 → phpwarden-2.1.1}/tests/test_feed_subscription.py +0 -0
- {phpwarden-2.0.3 → phpwarden-2.1.1}/tests/test_fleet.py +0 -0
- {phpwarden-2.0.3 → phpwarden-2.1.1}/tests/test_google_oauth.py +0 -0
- {phpwarden-2.0.3 → phpwarden-2.1.1}/tests/test_guard_live.py +0 -0
- {phpwarden-2.0.3 → phpwarden-2.1.1}/tests/test_mentions.py +0 -0
- {phpwarden-2.0.3 → phpwarden-2.1.1}/tests/test_reachability.py +0 -0
- {phpwarden-2.0.3 → phpwarden-2.1.1}/tests/test_saas.py +0 -0
- {phpwarden-2.0.3 → phpwarden-2.1.1}/tests/test_saas_billing.py +0 -0
- {phpwarden-2.0.3 → phpwarden-2.1.1}/tests/test_server.py +0 -0
- {phpwarden-2.0.3 → phpwarden-2.1.1}/tests/test_settings.py +0 -0
- {phpwarden-2.0.3 → phpwarden-2.1.1}/tests/test_shield.py +0 -0
- {phpwarden-2.0.3 → phpwarden-2.1.1}/tests/test_slack.py +0 -0
- {phpwarden-2.0.3 → phpwarden-2.1.1}/tests/test_sso.py +0 -0
- {phpwarden-2.0.3 → phpwarden-2.1.1}/tests/test_team.py +0 -0
- {phpwarden-2.0.3 → phpwarden-2.1.1}/tests/test_triage.py +0 -0
- {phpwarden-2.0.3 → phpwarden-2.1.1}/tests/test_webhook_idempotency.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: phpwarden
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.1.1
|
|
4
4
|
Summary: PHP vulnerability scanner for Composer, WordPress and the PHP engine — findings ranked by real-world exploitation (CISA KEV, then EPSS), not CVSS. Offline, zero deps.
|
|
5
5
|
Author: oroma-alfred
|
|
6
6
|
License-Expression: Apache-2.0
|
|
@@ -23,8 +23,8 @@ Dynamic: license-file
|
|
|
23
23
|
# phpwarden
|
|
24
24
|
|
|
25
25
|
**PHP vulnerability scanner that ranks findings by real-world exploitation,
|
|
26
|
-
not CVSS.** Of
|
|
27
|
-
exploited (CISA KEV, as of 2026-11-
|
|
26
|
+
not CVSS.** Of about 19,500 PHP vulnerabilities in the feed, 41 are known to be
|
|
27
|
+
exploited (CISA KEV, as of 2026-11-13). phpwarden puts those first, then sorts
|
|
28
28
|
by EPSS probability, then CVSS — so a `composer.lock` with 30 findings tells
|
|
29
29
|
you which one to fix today.
|
|
30
30
|
|
|
@@ -32,6 +32,13 @@ It scans the PHP engine/FPM version, Composer dependencies and WordPress
|
|
|
32
32
|
installs against one bundled, offline advisory feed. Zero runtime dependencies
|
|
33
33
|
(Python 3.8+), Apache-2.0.
|
|
34
34
|
|
|
35
|
+
**Reproducible benchmark:** on four real PHP stacks, phpwarden found 295 of 295
|
|
36
|
+
known vulnerabilities, `composer audit` 286 and OSV.dev 262. Of 297 findings,
|
|
37
|
+
100 were rated critical or high and 4 were actually exploited or likely to be;
|
|
38
|
+
phpwarden ranked each of those first or second in its project. Method, numbers
|
|
39
|
+
and a script to rerun it:
|
|
40
|
+
[the benchmark write-up](https://phpwarden.io/blog/phpwarden-vs-composer-audit-osv-2026-11).
|
|
41
|
+
|
|
35
42
|
```bash
|
|
36
43
|
$ phpwarden deps composer.lock
|
|
37
44
|
18 vulnerable package(s) in composer.lock; 0 actively exploited (KEV). Ranked by exploitation risk, then reachability:
|
|
@@ -51,6 +58,7 @@ $ phpwarden deps composer.lock
|
|
|
51
58
|
| PHP engine / FPM CVE exposure | `scan` | image & network scanners |
|
|
52
59
|
| Composer dependency CVEs | `deps` | Snyk, `composer audit` |
|
|
53
60
|
| WordPress core, plugin and theme CVEs | `wordpress` | Patchstack, Wordfence |
|
|
61
|
+
| WordPress file integrity (wordpress.org checksums, injected files) | `integrity` | Wordfence CLI malware-scan (partly) |
|
|
54
62
|
| Exploitation signatures in logs | `detect` | SIEM content |
|
|
55
63
|
| WAF blocking rules (PHP-specific) | `rules` | the gap a generic WAF leaves |
|
|
56
64
|
| Fleet exposure dashboard | `report` | the CNAPP's PHP view |
|
|
@@ -78,8 +86,9 @@ $ phpwarden deps composer.lock
|
|
|
78
86
|
```bash
|
|
79
87
|
composer require --dev phpwarden/phpwarden # PHP projects → vendor/bin/phpwarden
|
|
80
88
|
pipx install phpwarden # Python-tooling box
|
|
89
|
+
brew install oroma-alfred/tap/phpwarden # macOS / Linux with Homebrew
|
|
81
90
|
python3 phpwarden.pyz scan # single file, no install
|
|
82
|
-
docker
|
|
91
|
+
docker run --rm phpwarden/phpwarden scan --version 8.3.10 --sapi fpm --os linux # Docker Hub, amd64 + arm64
|
|
83
92
|
```
|
|
84
93
|
|
|
85
94
|
On modern macOS / Debian / Ubuntu a plain `pip install phpwarden` into the
|
|
@@ -90,8 +99,8 @@ system Python is blocked by [PEP 668](https://peps.python.org/pep-0668/); use
|
|
|
90
99
|
python3 -m venv ~/.venvs/phpwarden && ~/.venvs/phpwarden/bin/pip install phpwarden
|
|
91
100
|
```
|
|
92
101
|
|
|
93
|
-
Docker usage (mounted projects, CI, dashboard reporting) is
|
|
94
|
-
[
|
|
102
|
+
Docker usage (mounted projects, exit codes, CI, dashboard reporting) is on the
|
|
103
|
+
image's [Docker Hub page](https://hub.docker.com/r/phpwarden/phpwarden).
|
|
95
104
|
|
|
96
105
|
## Use
|
|
97
106
|
|
|
@@ -100,6 +109,7 @@ phpwarden scan # assess this host (auto-detects version/SA
|
|
|
100
109
|
phpwarden scan --version 8.3.10 --sapi fpm --os linux
|
|
101
110
|
phpwarden deps composer.lock # Composer dependencies, KEV → reachability → EPSS → CVSS
|
|
102
111
|
phpwarden wordpress /var/www/html # WordPress core, plugins, themes
|
|
112
|
+
phpwarden integrity /var/www/html # tampered or injected files (vs wordpress.org checksums)
|
|
103
113
|
phpwarden detect /var/log/nginx/access.log # exploit signatures in a log
|
|
104
114
|
phpwarden rules --format nginx --out php-block.conf # PHP-specific WAF rules (or modsecurity)
|
|
105
115
|
phpwarden report web01.json web02.json --out fleet.html # aggregate a fleet view
|
|
@@ -112,6 +122,21 @@ built for gating: `0` clean, `1` exposed / vulnerable / signature hits,
|
|
|
112
122
|
error, `5` `--report-to` upload failed on an otherwise clean run, `64` usage
|
|
113
123
|
error. Full table: `phpwarden --help`.
|
|
114
124
|
|
|
125
|
+
|
|
126
|
+
## Replacing Wordfence CLI
|
|
127
|
+
|
|
128
|
+
Wordfence closed new licences for its CLI in October 2026; Free licences stopped working on 2026-10-14 and Premium
|
|
129
|
+
licences are not renewed. phpwarden runs the same way (on the server, no plugin in the site) and covers:
|
|
130
|
+
|
|
131
|
+
| Wordfence CLI | phpwarden | Notes |
|
|
132
|
+
|---|---|---|
|
|
133
|
+
| `wordfence vuln-scan /path` | `phpwarden wordpress /path` | Same job, ranked by real-world exploitation; JSON/SARIF and CI exit codes. Also scans Composer and the PHP engine. |
|
|
134
|
+
| `wordfence malware-scan /path` | `phpwarden integrity /path` | Compares core and wordpress.org plugin files with official checksums; flags injected files, PHP in uploads and common backdoor code. **Not a signature scanner**: premium plugins and themes cannot be verified and are listed as such. |
|
|
135
|
+
| `wordfence remediate` | – | Reinstall the flagged component with WP-CLI. |
|
|
136
|
+
| `wordfence db-scan` | – | Not covered. |
|
|
137
|
+
|
|
138
|
+
Full guide: https://phpwarden.io/compare/phpwarden-vs-wordfence-cli#replace
|
|
139
|
+
|
|
115
140
|
## Send results to the dashboard
|
|
116
141
|
|
|
117
142
|
Any `scan`, `deps`, `wordpress` or `detect` run can post its result to
|
|
@@ -174,7 +199,7 @@ timer recipes are in [`docs/recipes.md`](docs/recipes.md).
|
|
|
174
199
|
|
|
175
200
|
The bundled community feed (currently 2026.10.31.2) works forever, offline:
|
|
176
201
|
|
|
177
|
-
- **~21,
|
|
202
|
+
- **~21,300 advisories**: ~8,800 Composer (from [OSV.dev](https://osv.dev) and
|
|
178
203
|
[FriendsOfPHP](https://github.com/FriendsOfPHP/security-advisories)),
|
|
179
204
|
~12,300 WordPress (from [NVD](https://nvd.nist.gov): plugin, core and theme),
|
|
180
205
|
and 145 PHP engine/FPM CVEs, including hand-curated entries with per-branch
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
# phpwarden
|
|
2
2
|
|
|
3
3
|
**PHP vulnerability scanner that ranks findings by real-world exploitation,
|
|
4
|
-
not CVSS.** Of
|
|
5
|
-
exploited (CISA KEV, as of 2026-11-
|
|
4
|
+
not CVSS.** Of about 19,500 PHP vulnerabilities in the feed, 41 are known to be
|
|
5
|
+
exploited (CISA KEV, as of 2026-11-13). phpwarden puts those first, then sorts
|
|
6
6
|
by EPSS probability, then CVSS — so a `composer.lock` with 30 findings tells
|
|
7
7
|
you which one to fix today.
|
|
8
8
|
|
|
@@ -10,6 +10,13 @@ It scans the PHP engine/FPM version, Composer dependencies and WordPress
|
|
|
10
10
|
installs against one bundled, offline advisory feed. Zero runtime dependencies
|
|
11
11
|
(Python 3.8+), Apache-2.0.
|
|
12
12
|
|
|
13
|
+
**Reproducible benchmark:** on four real PHP stacks, phpwarden found 295 of 295
|
|
14
|
+
known vulnerabilities, `composer audit` 286 and OSV.dev 262. Of 297 findings,
|
|
15
|
+
100 were rated critical or high and 4 were actually exploited or likely to be;
|
|
16
|
+
phpwarden ranked each of those first or second in its project. Method, numbers
|
|
17
|
+
and a script to rerun it:
|
|
18
|
+
[the benchmark write-up](https://phpwarden.io/blog/phpwarden-vs-composer-audit-osv-2026-11).
|
|
19
|
+
|
|
13
20
|
```bash
|
|
14
21
|
$ phpwarden deps composer.lock
|
|
15
22
|
18 vulnerable package(s) in composer.lock; 0 actively exploited (KEV). Ranked by exploitation risk, then reachability:
|
|
@@ -29,6 +36,7 @@ $ phpwarden deps composer.lock
|
|
|
29
36
|
| PHP engine / FPM CVE exposure | `scan` | image & network scanners |
|
|
30
37
|
| Composer dependency CVEs | `deps` | Snyk, `composer audit` |
|
|
31
38
|
| WordPress core, plugin and theme CVEs | `wordpress` | Patchstack, Wordfence |
|
|
39
|
+
| WordPress file integrity (wordpress.org checksums, injected files) | `integrity` | Wordfence CLI malware-scan (partly) |
|
|
32
40
|
| Exploitation signatures in logs | `detect` | SIEM content |
|
|
33
41
|
| WAF blocking rules (PHP-specific) | `rules` | the gap a generic WAF leaves |
|
|
34
42
|
| Fleet exposure dashboard | `report` | the CNAPP's PHP view |
|
|
@@ -56,8 +64,9 @@ $ phpwarden deps composer.lock
|
|
|
56
64
|
```bash
|
|
57
65
|
composer require --dev phpwarden/phpwarden # PHP projects → vendor/bin/phpwarden
|
|
58
66
|
pipx install phpwarden # Python-tooling box
|
|
67
|
+
brew install oroma-alfred/tap/phpwarden # macOS / Linux with Homebrew
|
|
59
68
|
python3 phpwarden.pyz scan # single file, no install
|
|
60
|
-
docker
|
|
69
|
+
docker run --rm phpwarden/phpwarden scan --version 8.3.10 --sapi fpm --os linux # Docker Hub, amd64 + arm64
|
|
61
70
|
```
|
|
62
71
|
|
|
63
72
|
On modern macOS / Debian / Ubuntu a plain `pip install phpwarden` into the
|
|
@@ -68,8 +77,8 @@ system Python is blocked by [PEP 668](https://peps.python.org/pep-0668/); use
|
|
|
68
77
|
python3 -m venv ~/.venvs/phpwarden && ~/.venvs/phpwarden/bin/pip install phpwarden
|
|
69
78
|
```
|
|
70
79
|
|
|
71
|
-
Docker usage (mounted projects, CI, dashboard reporting) is
|
|
72
|
-
[
|
|
80
|
+
Docker usage (mounted projects, exit codes, CI, dashboard reporting) is on the
|
|
81
|
+
image's [Docker Hub page](https://hub.docker.com/r/phpwarden/phpwarden).
|
|
73
82
|
|
|
74
83
|
## Use
|
|
75
84
|
|
|
@@ -78,6 +87,7 @@ phpwarden scan # assess this host (auto-detects version/SA
|
|
|
78
87
|
phpwarden scan --version 8.3.10 --sapi fpm --os linux
|
|
79
88
|
phpwarden deps composer.lock # Composer dependencies, KEV → reachability → EPSS → CVSS
|
|
80
89
|
phpwarden wordpress /var/www/html # WordPress core, plugins, themes
|
|
90
|
+
phpwarden integrity /var/www/html # tampered or injected files (vs wordpress.org checksums)
|
|
81
91
|
phpwarden detect /var/log/nginx/access.log # exploit signatures in a log
|
|
82
92
|
phpwarden rules --format nginx --out php-block.conf # PHP-specific WAF rules (or modsecurity)
|
|
83
93
|
phpwarden report web01.json web02.json --out fleet.html # aggregate a fleet view
|
|
@@ -90,6 +100,21 @@ built for gating: `0` clean, `1` exposed / vulnerable / signature hits,
|
|
|
90
100
|
error, `5` `--report-to` upload failed on an otherwise clean run, `64` usage
|
|
91
101
|
error. Full table: `phpwarden --help`.
|
|
92
102
|
|
|
103
|
+
|
|
104
|
+
## Replacing Wordfence CLI
|
|
105
|
+
|
|
106
|
+
Wordfence closed new licences for its CLI in October 2026; Free licences stopped working on 2026-10-14 and Premium
|
|
107
|
+
licences are not renewed. phpwarden runs the same way (on the server, no plugin in the site) and covers:
|
|
108
|
+
|
|
109
|
+
| Wordfence CLI | phpwarden | Notes |
|
|
110
|
+
|---|---|---|
|
|
111
|
+
| `wordfence vuln-scan /path` | `phpwarden wordpress /path` | Same job, ranked by real-world exploitation; JSON/SARIF and CI exit codes. Also scans Composer and the PHP engine. |
|
|
112
|
+
| `wordfence malware-scan /path` | `phpwarden integrity /path` | Compares core and wordpress.org plugin files with official checksums; flags injected files, PHP in uploads and common backdoor code. **Not a signature scanner**: premium plugins and themes cannot be verified and are listed as such. |
|
|
113
|
+
| `wordfence remediate` | – | Reinstall the flagged component with WP-CLI. |
|
|
114
|
+
| `wordfence db-scan` | – | Not covered. |
|
|
115
|
+
|
|
116
|
+
Full guide: https://phpwarden.io/compare/phpwarden-vs-wordfence-cli#replace
|
|
117
|
+
|
|
93
118
|
## Send results to the dashboard
|
|
94
119
|
|
|
95
120
|
Any `scan`, `deps`, `wordpress` or `detect` run can post its result to
|
|
@@ -152,7 +177,7 @@ timer recipes are in [`docs/recipes.md`](docs/recipes.md).
|
|
|
152
177
|
|
|
153
178
|
The bundled community feed (currently 2026.10.31.2) works forever, offline:
|
|
154
179
|
|
|
155
|
-
- **~21,
|
|
180
|
+
- **~21,300 advisories**: ~8,800 Composer (from [OSV.dev](https://osv.dev) and
|
|
156
181
|
[FriendsOfPHP](https://github.com/FriendsOfPHP/security-advisories)),
|
|
157
182
|
~12,300 WordPress (from [NVD](https://nvd.nist.gov): plugin, core and theme),
|
|
158
183
|
and 145 PHP engine/FPM CVEs, including hand-curated entries with per-branch
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "phpwarden"
|
|
7
|
-
version = "2.
|
|
7
|
+
version = "2.1.1"
|
|
8
8
|
description = "PHP vulnerability scanner for Composer, WordPress and the PHP engine — findings ranked by real-world exploitation (CISA KEV, then EPSS), not CVSS. Offline, zero deps."
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.8"
|
|
@@ -372,6 +372,39 @@ def _wordpress(args):
|
|
|
372
372
|
return _combine(1 if findings else 0, _maybe_report(args, doc))
|
|
373
373
|
|
|
374
374
|
|
|
375
|
+
def _integrity(args):
|
|
376
|
+
from phpwarden import integrity as integ
|
|
377
|
+
res = integ.check(args.path, locale=args.locale, plugins=not args.no_plugins)
|
|
378
|
+
doc = integ.to_doc(res)
|
|
379
|
+
if args.json:
|
|
380
|
+
print(json.dumps(doc, indent=2))
|
|
381
|
+
return 1 if res.tampered else 0
|
|
382
|
+
if not res.core_version:
|
|
383
|
+
print(f"{args.path}: no WordPress install detected at that path")
|
|
384
|
+
return 2
|
|
385
|
+
labels = {"php-in-uploads": "PHP file in uploads", "unexpected": "does not belong",
|
|
386
|
+
"modified": "modified", "missing": "missing"}
|
|
387
|
+
bad = [i for i in res.issues if i.kind != "missing"]
|
|
388
|
+
print(f"WordPress {res.core_version} at {args.path}: {res.files_checked} files compared with wordpress.org, "
|
|
389
|
+
f"{len(bad)} problem{'s' if len(bad) != 1 else ''}.")
|
|
390
|
+
for i in res.issues:
|
|
391
|
+
flag = " SUSPICIOUS" if i.suspicious else ""
|
|
392
|
+
print(f"\n {labels.get(i.kind, i.kind):20} {i.path} ({i.component}){flag}")
|
|
393
|
+
for pid in i.suspicious:
|
|
394
|
+
print(f" matches: {integ.describe(pid)}")
|
|
395
|
+
if res.verified:
|
|
396
|
+
print(f"\n verified against official checksums: {len(res.verified)} component(s)")
|
|
397
|
+
if res.unverified:
|
|
398
|
+
print(f" could not be verified: {len(res.unverified)} component(s)")
|
|
399
|
+
for u in res.unverified[:40]:
|
|
400
|
+
print(f" {u['component']}: {u['reason']}")
|
|
401
|
+
if not res.issues:
|
|
402
|
+
print("\n No modified or unexpected files in the components that could be verified.")
|
|
403
|
+
print("\n This compares files with wordpress.org checksums and looks for common backdoor code.\n"
|
|
404
|
+
" It is not a signature-based malware scanner.")
|
|
405
|
+
return 1 if res.tampered else 0
|
|
406
|
+
|
|
407
|
+
|
|
375
408
|
def _report(args):
|
|
376
409
|
rows = reportgen.load_rows(args.files)
|
|
377
410
|
feed = FeedManager().current()
|
|
@@ -438,6 +471,14 @@ def main(argv=None):
|
|
|
438
471
|
_report_args(wpc)
|
|
439
472
|
wpc.set_defaults(func=_wordpress)
|
|
440
473
|
|
|
474
|
+
ig = sub.add_parser("integrity", help="check WordPress core and plugin files against wordpress.org "
|
|
475
|
+
"checksums; flag injected files and backdoor code")
|
|
476
|
+
ig.add_argument("path", help="path to the WordPress root")
|
|
477
|
+
ig.add_argument("--locale", default="en_US", help="WordPress locale of the install (default en_US)")
|
|
478
|
+
ig.add_argument("--no-plugins", action="store_true", help="check core and uploads only")
|
|
479
|
+
ig.add_argument("--json", action="store_true")
|
|
480
|
+
ig.set_defaults(func=_integrity)
|
|
481
|
+
|
|
441
482
|
rp = sub.add_parser("report", help="aggregate JSON results into an HTML fleet dashboard")
|
|
442
483
|
rp.add_argument("files", nargs="+", help="JSON files from scan/deps/wordpress --json")
|
|
443
484
|
rp.add_argument("--out", help="write HTML to a file instead of stdout")
|