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.
Files changed (62) hide show
  1. {phpwarden-2.0.2 → phpwarden-2.1.0}/PKG-INFO +4 -3
  2. {phpwarden-2.0.2 → phpwarden-2.1.0}/README.md +1 -0
  3. {phpwarden-2.0.2 → phpwarden-2.1.0}/pyproject.toml +3 -3
  4. {phpwarden-2.0.2 → phpwarden-2.1.0}/src/phpwarden/__init__.py +1 -1
  5. {phpwarden-2.0.2 → phpwarden-2.1.0}/src/phpwarden/cli.py +41 -0
  6. {phpwarden-2.0.2 → phpwarden-2.1.0}/src/phpwarden/data/php-cve-feed.json +124937 -23947
  7. phpwarden-2.1.0/src/phpwarden/integrity.py +254 -0
  8. {phpwarden-2.0.2 → phpwarden-2.1.0}/src/phpwarden.egg-info/PKG-INFO +4 -3
  9. {phpwarden-2.0.2 → phpwarden-2.1.0}/src/phpwarden.egg-info/SOURCES.txt +4 -0
  10. phpwarden-2.1.0/tests/test_agency.py +259 -0
  11. {phpwarden-2.0.2 → phpwarden-2.1.0}/tests/test_engine_feed.py +8 -0
  12. phpwarden-2.1.0/tests/test_integrity.py +109 -0
  13. phpwarden-2.1.0/tests/test_store_connections.py +40 -0
  14. {phpwarden-2.0.2 → phpwarden-2.1.0}/LICENSE +0 -0
  15. {phpwarden-2.0.2 → phpwarden-2.1.0}/setup.cfg +0 -0
  16. {phpwarden-2.0.2 → phpwarden-2.1.0}/src/phpwarden/deps.py +0 -0
  17. {phpwarden-2.0.2 → phpwarden-2.1.0}/src/phpwarden/detect.py +0 -0
  18. {phpwarden-2.0.2 → phpwarden-2.1.0}/src/phpwarden/engine.py +0 -0
  19. {phpwarden-2.0.2 → phpwarden-2.1.0}/src/phpwarden/env.py +0 -0
  20. {phpwarden-2.0.2 → phpwarden-2.1.0}/src/phpwarden/feed.py +0 -0
  21. {phpwarden-2.0.2 → phpwarden-2.1.0}/src/phpwarden/guard.py +0 -0
  22. {phpwarden-2.0.2 → phpwarden-2.1.0}/src/phpwarden/report.py +0 -0
  23. {phpwarden-2.0.2 → phpwarden-2.1.0}/src/phpwarden/rules.py +0 -0
  24. {phpwarden-2.0.2 → phpwarden-2.1.0}/src/phpwarden/version.py +0 -0
  25. {phpwarden-2.0.2 → phpwarden-2.1.0}/src/phpwarden/vulndb.py +0 -0
  26. {phpwarden-2.0.2 → phpwarden-2.1.0}/src/phpwarden/wordpress.py +0 -0
  27. {phpwarden-2.0.2 → phpwarden-2.1.0}/src/phpwarden.egg-info/dependency_links.txt +0 -0
  28. {phpwarden-2.0.2 → phpwarden-2.1.0}/src/phpwarden.egg-info/entry_points.txt +0 -0
  29. {phpwarden-2.0.2 → phpwarden-2.1.0}/src/phpwarden.egg-info/top_level.txt +0 -0
  30. {phpwarden-2.0.2 → phpwarden-2.1.0}/tests/test_accounts.py +0 -0
  31. {phpwarden-2.0.2 → phpwarden-2.1.0}/tests/test_advisories.py +0 -0
  32. {phpwarden-2.0.2 → phpwarden-2.1.0}/tests/test_assignment.py +0 -0
  33. {phpwarden-2.0.2 → phpwarden-2.1.0}/tests/test_audit.py +0 -0
  34. {phpwarden-2.0.2 → phpwarden-2.1.0}/tests/test_billing.py +0 -0
  35. {phpwarden-2.0.2 → phpwarden-2.1.0}/tests/test_cli_edges.py +0 -0
  36. {phpwarden-2.0.2 → phpwarden-2.1.0}/tests/test_connect_flow.py +0 -0
  37. {phpwarden-2.0.2 → phpwarden-2.1.0}/tests/test_dashboard_states.py +0 -0
  38. {phpwarden-2.0.2 → phpwarden-2.1.0}/tests/test_deps_and_rules.py +0 -0
  39. {phpwarden-2.0.2 → phpwarden-2.1.0}/tests/test_detection_validation.py +0 -0
  40. {phpwarden-2.0.2 → phpwarden-2.1.0}/tests/test_developer.py +0 -0
  41. {phpwarden-2.0.2 → phpwarden-2.1.0}/tests/test_discussion.py +0 -0
  42. {phpwarden-2.0.2 → phpwarden-2.1.0}/tests/test_e2e_readiness.py +0 -0
  43. {phpwarden-2.0.2 → phpwarden-2.1.0}/tests/test_email.py +0 -0
  44. {phpwarden-2.0.2 → phpwarden-2.1.0}/tests/test_engine.py +0 -0
  45. {phpwarden-2.0.2 → phpwarden-2.1.0}/tests/test_feed_license.py +0 -0
  46. {phpwarden-2.0.2 → phpwarden-2.1.0}/tests/test_feed_subscription.py +0 -0
  47. {phpwarden-2.0.2 → phpwarden-2.1.0}/tests/test_fleet.py +0 -0
  48. {phpwarden-2.0.2 → phpwarden-2.1.0}/tests/test_google_oauth.py +0 -0
  49. {phpwarden-2.0.2 → phpwarden-2.1.0}/tests/test_guard_live.py +0 -0
  50. {phpwarden-2.0.2 → phpwarden-2.1.0}/tests/test_mentions.py +0 -0
  51. {phpwarden-2.0.2 → phpwarden-2.1.0}/tests/test_reachability.py +0 -0
  52. {phpwarden-2.0.2 → phpwarden-2.1.0}/tests/test_saas.py +0 -0
  53. {phpwarden-2.0.2 → phpwarden-2.1.0}/tests/test_saas_billing.py +0 -0
  54. {phpwarden-2.0.2 → phpwarden-2.1.0}/tests/test_server.py +0 -0
  55. {phpwarden-2.0.2 → phpwarden-2.1.0}/tests/test_settings.py +0 -0
  56. {phpwarden-2.0.2 → phpwarden-2.1.0}/tests/test_shield.py +0 -0
  57. {phpwarden-2.0.2 → phpwarden-2.1.0}/tests/test_slack.py +0 -0
  58. {phpwarden-2.0.2 → phpwarden-2.1.0}/tests/test_sso.py +0 -0
  59. {phpwarden-2.0.2 → phpwarden-2.1.0}/tests/test_team.py +0 -0
  60. {phpwarden-2.0.2 → phpwarden-2.1.0}/tests/test_triage.py +0 -0
  61. {phpwarden-2.0.2 → phpwarden-2.1.0}/tests/test_webhook_idempotency.py +0 -0
  62. {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.2
4
- Summary: PHP exposure and exploitation guard — assess any PHP host against an evolving CVE feed, and watch PHP-FPM for active exploitation
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,vulnerability,exploitation,detection,rce
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.2"
8
- description = "PHP exposure and exploitation guard — assess any PHP host against an evolving CVE feed, and watch PHP-FPM for active exploitation"
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", "vulnerability", "exploitation", "detection", "rce"]
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",
@@ -5,4 +5,4 @@ environment against an evolving knowledge base of PHP CVEs (the feed), and can
5
5
  watch PHP-FPM for active exploitation. The engine is open; the CVE feed is the
6
6
  part a subscription keeps current.
7
7
  """
8
- __version__ = "2.0.2"
8
+ __version__ = "2.1.0"
@@ -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")