phpwarden 2.0.2__tar.gz → 2.1.0__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.2 → phpwarden-2.1.0}/PKG-INFO +4 -3
- {phpwarden-2.0.2 → phpwarden-2.1.0}/README.md +1 -0
- {phpwarden-2.0.2 → phpwarden-2.1.0}/pyproject.toml +3 -3
- {phpwarden-2.0.2 → phpwarden-2.1.0}/src/phpwarden/__init__.py +1 -1
- {phpwarden-2.0.2 → phpwarden-2.1.0}/src/phpwarden/cli.py +41 -0
- {phpwarden-2.0.2 → phpwarden-2.1.0}/src/phpwarden/data/php-cve-feed.json +124937 -23947
- phpwarden-2.1.0/src/phpwarden/integrity.py +254 -0
- {phpwarden-2.0.2 → phpwarden-2.1.0}/src/phpwarden.egg-info/PKG-INFO +4 -3
- {phpwarden-2.0.2 → phpwarden-2.1.0}/src/phpwarden.egg-info/SOURCES.txt +4 -0
- phpwarden-2.1.0/tests/test_agency.py +259 -0
- {phpwarden-2.0.2 → phpwarden-2.1.0}/tests/test_engine_feed.py +8 -0
- phpwarden-2.1.0/tests/test_integrity.py +109 -0
- phpwarden-2.1.0/tests/test_store_connections.py +40 -0
- {phpwarden-2.0.2 → phpwarden-2.1.0}/LICENSE +0 -0
- {phpwarden-2.0.2 → phpwarden-2.1.0}/setup.cfg +0 -0
- {phpwarden-2.0.2 → phpwarden-2.1.0}/src/phpwarden/deps.py +0 -0
- {phpwarden-2.0.2 → phpwarden-2.1.0}/src/phpwarden/detect.py +0 -0
- {phpwarden-2.0.2 → phpwarden-2.1.0}/src/phpwarden/engine.py +0 -0
- {phpwarden-2.0.2 → phpwarden-2.1.0}/src/phpwarden/env.py +0 -0
- {phpwarden-2.0.2 → phpwarden-2.1.0}/src/phpwarden/feed.py +0 -0
- {phpwarden-2.0.2 → phpwarden-2.1.0}/src/phpwarden/guard.py +0 -0
- {phpwarden-2.0.2 → phpwarden-2.1.0}/src/phpwarden/report.py +0 -0
- {phpwarden-2.0.2 → phpwarden-2.1.0}/src/phpwarden/rules.py +0 -0
- {phpwarden-2.0.2 → phpwarden-2.1.0}/src/phpwarden/version.py +0 -0
- {phpwarden-2.0.2 → phpwarden-2.1.0}/src/phpwarden/vulndb.py +0 -0
- {phpwarden-2.0.2 → phpwarden-2.1.0}/src/phpwarden/wordpress.py +0 -0
- {phpwarden-2.0.2 → phpwarden-2.1.0}/src/phpwarden.egg-info/dependency_links.txt +0 -0
- {phpwarden-2.0.2 → phpwarden-2.1.0}/src/phpwarden.egg-info/entry_points.txt +0 -0
- {phpwarden-2.0.2 → phpwarden-2.1.0}/src/phpwarden.egg-info/top_level.txt +0 -0
- {phpwarden-2.0.2 → phpwarden-2.1.0}/tests/test_accounts.py +0 -0
- {phpwarden-2.0.2 → phpwarden-2.1.0}/tests/test_advisories.py +0 -0
- {phpwarden-2.0.2 → phpwarden-2.1.0}/tests/test_assignment.py +0 -0
- {phpwarden-2.0.2 → phpwarden-2.1.0}/tests/test_audit.py +0 -0
- {phpwarden-2.0.2 → phpwarden-2.1.0}/tests/test_billing.py +0 -0
- {phpwarden-2.0.2 → phpwarden-2.1.0}/tests/test_cli_edges.py +0 -0
- {phpwarden-2.0.2 → phpwarden-2.1.0}/tests/test_connect_flow.py +0 -0
- {phpwarden-2.0.2 → phpwarden-2.1.0}/tests/test_dashboard_states.py +0 -0
- {phpwarden-2.0.2 → phpwarden-2.1.0}/tests/test_deps_and_rules.py +0 -0
- {phpwarden-2.0.2 → phpwarden-2.1.0}/tests/test_detection_validation.py +0 -0
- {phpwarden-2.0.2 → phpwarden-2.1.0}/tests/test_developer.py +0 -0
- {phpwarden-2.0.2 → phpwarden-2.1.0}/tests/test_discussion.py +0 -0
- {phpwarden-2.0.2 → phpwarden-2.1.0}/tests/test_e2e_readiness.py +0 -0
- {phpwarden-2.0.2 → phpwarden-2.1.0}/tests/test_email.py +0 -0
- {phpwarden-2.0.2 → phpwarden-2.1.0}/tests/test_engine.py +0 -0
- {phpwarden-2.0.2 → phpwarden-2.1.0}/tests/test_feed_license.py +0 -0
- {phpwarden-2.0.2 → phpwarden-2.1.0}/tests/test_feed_subscription.py +0 -0
- {phpwarden-2.0.2 → phpwarden-2.1.0}/tests/test_fleet.py +0 -0
- {phpwarden-2.0.2 → phpwarden-2.1.0}/tests/test_google_oauth.py +0 -0
- {phpwarden-2.0.2 → phpwarden-2.1.0}/tests/test_guard_live.py +0 -0
- {phpwarden-2.0.2 → phpwarden-2.1.0}/tests/test_mentions.py +0 -0
- {phpwarden-2.0.2 → phpwarden-2.1.0}/tests/test_reachability.py +0 -0
- {phpwarden-2.0.2 → phpwarden-2.1.0}/tests/test_saas.py +0 -0
- {phpwarden-2.0.2 → phpwarden-2.1.0}/tests/test_saas_billing.py +0 -0
- {phpwarden-2.0.2 → phpwarden-2.1.0}/tests/test_server.py +0 -0
- {phpwarden-2.0.2 → phpwarden-2.1.0}/tests/test_settings.py +0 -0
- {phpwarden-2.0.2 → phpwarden-2.1.0}/tests/test_shield.py +0 -0
- {phpwarden-2.0.2 → phpwarden-2.1.0}/tests/test_slack.py +0 -0
- {phpwarden-2.0.2 → phpwarden-2.1.0}/tests/test_sso.py +0 -0
- {phpwarden-2.0.2 → phpwarden-2.1.0}/tests/test_team.py +0 -0
- {phpwarden-2.0.2 → phpwarden-2.1.0}/tests/test_triage.py +0 -0
- {phpwarden-2.0.2 → phpwarden-2.1.0}/tests/test_webhook_idempotency.py +0 -0
- {phpwarden-2.0.2 → phpwarden-2.1.0}/tests/test_wordpress_and_report.py +0 -0
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: phpwarden
|
|
3
|
-
Version: 2.0
|
|
4
|
-
Summary: PHP
|
|
3
|
+
Version: 2.1.0
|
|
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
|
|
7
7
|
Project-URL: Homepage, https://phpwarden.io
|
|
8
8
|
Project-URL: Source, https://github.com/oroma-alfred/phpwarden
|
|
9
9
|
Project-URL: Issues, https://github.com/oroma-alfred/phpwarden/issues
|
|
10
|
-
Keywords: php,php-fpm,security,cve,
|
|
10
|
+
Keywords: php,composer,wordpress,php-fpm,security,vulnerability,cve,kev,epss,sca,scanner
|
|
11
11
|
Classifier: Development Status :: 4 - Beta
|
|
12
12
|
Classifier: Environment :: Console
|
|
13
13
|
Classifier: Intended Audience :: System Administrators
|
|
@@ -100,6 +100,7 @@ phpwarden scan # assess this host (auto-detects version/SA
|
|
|
100
100
|
phpwarden scan --version 8.3.10 --sapi fpm --os linux
|
|
101
101
|
phpwarden deps composer.lock # Composer dependencies, KEV → reachability → EPSS → CVSS
|
|
102
102
|
phpwarden wordpress /var/www/html # WordPress core, plugins, themes
|
|
103
|
+
phpwarden integrity /var/www/html # tampered or injected files (vs wordpress.org checksums)
|
|
103
104
|
phpwarden detect /var/log/nginx/access.log # exploit signatures in a log
|
|
104
105
|
phpwarden rules --format nginx --out php-block.conf # PHP-specific WAF rules (or modsecurity)
|
|
105
106
|
phpwarden report web01.json web02.json --out fleet.html # aggregate a fleet view
|
|
@@ -78,6 +78,7 @@ phpwarden scan # assess this host (auto-detects version/SA
|
|
|
78
78
|
phpwarden scan --version 8.3.10 --sapi fpm --os linux
|
|
79
79
|
phpwarden deps composer.lock # Composer dependencies, KEV → reachability → EPSS → CVSS
|
|
80
80
|
phpwarden wordpress /var/www/html # WordPress core, plugins, themes
|
|
81
|
+
phpwarden integrity /var/www/html # tampered or injected files (vs wordpress.org checksums)
|
|
81
82
|
phpwarden detect /var/log/nginx/access.log # exploit signatures in a log
|
|
82
83
|
phpwarden rules --format nginx --out php-block.conf # PHP-specific WAF rules (or modsecurity)
|
|
83
84
|
phpwarden report web01.json web02.json --out fleet.html # aggregate a fleet view
|
|
@@ -4,14 +4,14 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "phpwarden"
|
|
7
|
-
version = "2.0
|
|
8
|
-
description = "PHP
|
|
7
|
+
version = "2.1.0"
|
|
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"
|
|
11
11
|
license = "Apache-2.0"
|
|
12
12
|
license-files = ["LICENSE"]
|
|
13
13
|
authors = [{ name = "oroma-alfred" }]
|
|
14
|
-
keywords = ["php", "php-fpm", "security", "cve", "
|
|
14
|
+
keywords = ["php", "composer", "wordpress", "php-fpm", "security", "vulnerability", "cve", "kev", "epss", "sca", "scanner"]
|
|
15
15
|
classifiers = [
|
|
16
16
|
"Development Status :: 4 - Beta",
|
|
17
17
|
"Environment :: Console",
|
|
@@ -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")
|