wpsecscan 2.7.3__tar.gz → 2.8.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 (553) hide show
  1. {wpsecscan-2.7.3/wpsecscan.egg-info → wpsecscan-2.8.0}/PKG-INFO +13 -2
  2. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/pyproject.toml +26 -4
  3. wpsecscan-2.8.0/tests/test_edu_v27.py +157 -0
  4. wpsecscan-2.8.0/tests/test_perf_v27.py +203 -0
  5. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/tests/test_round_q.py +7 -4
  6. wpsecscan-2.8.0/tests/test_trust_v27.py +146 -0
  7. wpsecscan-2.8.0/tests/test_v280_critical_regressions.py +93 -0
  8. wpsecscan-2.8.0/tests/test_v280_wave2_regressions.py +261 -0
  9. wpsecscan-2.8.0/wpsecscan/__init__.py +1 -0
  10. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/__main__.py +54 -12
  11. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/ai_assist.py +25 -0
  12. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/ai_safety.py +14 -21
  13. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/api_server.py +101 -6
  14. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/__init__.py +8 -0
  15. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/csp.py +25 -0
  16. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/csrf_nonce.py +8 -1
  17. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/csv_export_csp.py +14 -4
  18. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/email_security_deep.py +11 -0
  19. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/gdpr_dsr_endpoint_enum.py +9 -2
  20. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/gutenberg_blocks.py +7 -1
  21. wpsecscan-2.8.0/wpsecscan/checks/headless_cors_lockdown.py +94 -0
  22. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/referenced_buckets.py +8 -3
  23. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/server_stack_reveal.py +5 -1
  24. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/subdomains.py +25 -3
  25. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/tls_deep.py +39 -2
  26. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/tls_headers.py +8 -2
  27. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/tls_reneg_dos.py +12 -3
  28. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/wallet_seed_phrase_leak.py +16 -2
  29. wpsecscan-2.8.0/wpsecscan/checks/wc_coupon_enum.py +116 -0
  30. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/websocket_audit.py +14 -4
  31. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/daemon/_legacy.py +47 -6
  32. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/data/check_tags.json +3 -1
  33. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/data/compliance_map.json +10 -0
  34. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/data/report.html.j2 +70 -0
  35. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/gui.py +89 -0
  36. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/http.py +11 -1
  37. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/integrations_v27.py +10 -1
  38. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/mobile_api.py +15 -1
  39. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/mobile_v27.py +49 -0
  40. wpsecscan-2.8.0/wpsecscan/perf/__init__.py +17 -0
  41. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/perf/_legacy.py +18 -29
  42. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/reporters/console.py +4 -1
  43. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/reporters/json_out.py +23 -1
  44. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/reporters/markdown.py +11 -7
  45. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/reporters/sarif.py +9 -3
  46. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/workflow_cmds.py +11 -1
  47. {wpsecscan-2.7.3 → wpsecscan-2.8.0/wpsecscan.egg-info}/PKG-INFO +13 -2
  48. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan.egg-info/SOURCES.txt +7 -0
  49. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan.egg-info/entry_points.txt +1 -0
  50. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan.egg-info/requires.txt +15 -1
  51. wpsecscan-2.7.3/wpsecscan/__init__.py +0 -1
  52. wpsecscan-2.7.3/wpsecscan/perf/__init__.py +0 -12
  53. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/LICENSE +0 -0
  54. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/NOTICE +0 -0
  55. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/README.md +0 -0
  56. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/setup.cfg +0 -0
  57. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/tests/test_audit_fixes.py +0 -0
  58. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/tests/test_audit_round_r.py +0 -0
  59. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/tests/test_board_one_pager.py +0 -0
  60. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/tests/test_burp_zap_import.py +0 -0
  61. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/tests/test_cache.py +0 -0
  62. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/tests/test_checks.py +0 -0
  63. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/tests/test_confidence_eta_tags.py +0 -0
  64. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/tests/test_creds_vault_cli.py +0 -0
  65. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/tests/test_default_creds.py +0 -0
  66. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/tests/test_diff_agency.py +0 -0
  67. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/tests/test_gh_check_run.py +0 -0
  68. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/tests/test_global_sigs_regression.py +0 -0
  69. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/tests/test_integrations_graphql_escape.py +0 -0
  70. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/tests/test_login_throttle.py +0 -0
  71. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/tests/test_login_throttle_deep.py +0 -0
  72. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/tests/test_marketplace_install_url_guard.py +0 -0
  73. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/tests/test_mobile_api_traversal.py +0 -0
  74. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/tests/test_new_check_inventory.py +0 -0
  75. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/tests/test_new_checks.py +0 -0
  76. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/tests/test_new_checks_aggressive.py +0 -0
  77. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/tests/test_new_checks_quality.py +0 -0
  78. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/tests/test_notify.py +0 -0
  79. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/tests/test_password_audit.py +0 -0
  80. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/tests/test_payloads.py +0 -0
  81. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/tests/test_phase5.py +0 -0
  82. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/tests/test_playbook.py +0 -0
  83. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/tests/test_prove.py +0 -0
  84. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/tests/test_reference_diff.py +0 -0
  85. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/tests/test_reference_diff_traversal.py +0 -0
  86. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/tests/test_risk_score.py +0 -0
  87. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/tests/test_round_54.py +0 -0
  88. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/tests/test_round_55.py +0 -0
  89. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/tests/test_round_56_activity.py +0 -0
  90. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/tests/test_round_57.py +0 -0
  91. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/tests/test_round_58.py +0 -0
  92. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/tests/test_round_59.py +0 -0
  93. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/tests/test_round_60.py +0 -0
  94. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/tests/test_round_61.py +0 -0
  95. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/tests/test_round_62.py +0 -0
  96. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/tests/test_round_63.py +0 -0
  97. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/tests/test_round_64.py +0 -0
  98. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/tests/test_round_65.py +0 -0
  99. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/tests/test_scan_zip.py +0 -0
  100. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/tests/test_scheduler.py +0 -0
  101. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/tests/test_scheduler_cron_dow.py +0 -0
  102. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/tests/test_siem.py +0 -0
  103. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/tests/test_sla.py +0 -0
  104. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/tests/test_slack_app.py +0 -0
  105. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/tests/test_ssh_audit.py +0 -0
  106. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/tests/test_user_template.py +0 -0
  107. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/tests/test_v272_audit_log_constant_time.py +0 -0
  108. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/tests/test_v272_marketplace_sigstore_identity.py +0 -0
  109. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/tests/test_v272_wave2_regressions.py +0 -0
  110. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/tests/test_v272_wave3_regressions.py +0 -0
  111. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/tests/test_v272_wave4_regressions.py +0 -0
  112. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/tests/test_v273_critical_regressions.py +0 -0
  113. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/tests/test_v273_wave2_regressions.py +0 -0
  114. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/tests/test_v273_wave3_companion.py +0 -0
  115. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/tests/test_v273_wave5_audit_log_wired.py +0 -0
  116. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/_util.py +0 -0
  117. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/activity.py +0 -0
  118. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/ai_fp_predictor.py +0 -0
  119. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/ai_triage.py +0 -0
  120. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/ai_triage_ui.py +0 -0
  121. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/analytics.py +0 -0
  122. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/attack_checkpoint.py +0 -0
  123. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/attack_scripts.py +0 -0
  124. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/auth/__init__.py +0 -0
  125. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/auth/approval_workflow.py +0 -0
  126. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/auth/audit_log.py +0 -0
  127. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/auth/rbac.py +0 -0
  128. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/auth/sso_oidc.py +0 -0
  129. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/auth/sso_saml.py +0 -0
  130. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/auto_pr.py +0 -0
  131. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/auto_update.py +0 -0
  132. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/baseline.py +0 -0
  133. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/branding.py +0 -0
  134. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/bug_report.py +0 -0
  135. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/burp_import.py +0 -0
  136. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/cache.py +0 -0
  137. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/check_health.py +0 -0
  138. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/_template.py +0 -0
  139. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/a11y_deep.py +0 -0
  140. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/a11y_lite.py +0 -0
  141. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/a11y_wcag_aaa.py +0 -0
  142. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/abuseipdb_lookup.py +0 -0
  143. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/admin_ajax_brute_surface.py +0 -0
  144. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/admin_invite_link_scan.py +0 -0
  145. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/ai_agent_webhook_leak.py +0 -0
  146. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/ai_chatbot_endpoint_leak.py +0 -0
  147. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/ai_plugin_prompt_storage.py +0 -0
  148. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/ai_prompt_injection_passive.py +0 -0
  149. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/ajax_surface.py +0 -0
  150. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/algolia_elastic_frontend_keys.py +0 -0
  151. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/amp_transitional_redirect.py +0 -0
  152. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/app_passwords.py +0 -0
  153. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/app_passwords_stale_audit.py +0 -0
  154. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/auth_modernisation.py +0 -0
  155. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/authenticated.py +0 -0
  156. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/backup_exposure.py +0 -0
  157. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/backup_file_fuzz.py +0 -0
  158. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/block_bindings_exposure.py +0 -0
  159. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/block_style_variations_url.py +0 -0
  160. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/brand_monitor.py +0 -0
  161. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/bucket_shadow_takeover.py +0 -0
  162. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/cache_headers.py +0 -0
  163. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/cache_poisoning.py +0 -0
  164. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/cache_poisoning_v2.py +0 -0
  165. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/cdn_edge_audit.py +0 -0
  166. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/cloud_metadata_ssrf.py +0 -0
  167. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/cloudflare_origin_leak.py +0 -0
  168. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/companion_advanced.py +0 -0
  169. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/companion_v13.py +0 -0
  170. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/companion_v14.py +0 -0
  171. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/compliance_frameworks.py +0 -0
  172. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/composer_lock_audit.py +0 -0
  173. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/composer_npm_typosquat.py +0 -0
  174. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/cookie_consent.py +0 -0
  175. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/cookie_consent_desync.py +0 -0
  176. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/cookies.py +0 -0
  177. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/core_checksums.py +0 -0
  178. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/core_cves.py +0 -0
  179. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/core_tampering.py +0 -0
  180. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/core_version.py +0 -0
  181. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/cors.py +0 -0
  182. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/crlf_location_injection.py +0 -0
  183. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/crypto_agility.py +0 -0
  184. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/crypto_payment_callback_audit.py +0 -0
  185. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/cryptominer_js_injection.py +0 -0
  186. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/csp_report_endpoint.py +0 -0
  187. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/csrf_entropy.py +0 -0
  188. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/ct_log_recent_certs.py +0 -0
  189. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/ct_log_shadow_cert.py +0 -0
  190. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/db_admin_login_probe.py +0 -0
  191. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/db_trigger_audit.py +0 -0
  192. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/debug_leaks.py +0 -0
  193. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/debug_log_pii_sniff.py +0 -0
  194. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/default_creds.py +0 -0
  195. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/dev_params.py +0 -0
  196. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/directory_listing.py +0 -0
  197. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/dns_deep.py +0 -0
  198. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/dns_rebinding.py +0 -0
  199. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/dns_security.py +0 -0
  200. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/dns_templates.py +0 -0
  201. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/dom_xss_headless.py +0 -0
  202. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/email_obfuscation_audit.py +0 -0
  203. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/env_file_enum.py +0 -0
  204. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/error_pages.py +0 -0
  205. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/exposed_files.py +0 -0
  206. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/favicon_fingerprint.py +0 -0
  207. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/file_upload.py +0 -0
  208. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/font_library_api_ssrf.py +0 -0
  209. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/forced_browse.py +0 -0
  210. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/form_builder_upload_bypass.py +0 -0
  211. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/gdpr_dsr.py +0 -0
  212. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/git_dir_deep_scan.py +0 -0
  213. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/github_actions_workflow_leak.py +0 -0
  214. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/github_leak_search.py +0 -0
  215. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/graphql_dos.py +0 -0
  216. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/graphql_field_authz_deep.py +0 -0
  217. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/gtm_inventory.py +0 -0
  218. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/header_smuggling_case.py +0 -0
  219. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/headless_templates.py +0 -0
  220. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/headless_vercel_netlify_detect.py +0 -0
  221. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/headless_wp_audit.py +0 -0
  222. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/heartbeat_abuse.py +0 -0
  223. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/heartbeat_frontend.py +0 -0
  224. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/helm_compose_leak.py +0 -0
  225. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/hibp.py +0 -0
  226. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/honeypot_admin.py +0 -0
  227. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/host_header_validation.py +0 -0
  228. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/host_platform_detect.py +0 -0
  229. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/host_recon.py +0 -0
  230. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/hosting_platform_audit.py +0 -0
  231. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/hostname_collision.py +0 -0
  232. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/hpp.py +0 -0
  233. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/hsts_preload_eligibility.py +0 -0
  234. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/hsts_preload_mismatch.py +0 -0
  235. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/html_api_csp_nonce.py +0 -0
  236. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/http2_settings.py +0 -0
  237. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/http2_smuggling.py +0 -0
  238. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/http3_fingerprint.py +0 -0
  239. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/http_methods.py +0 -0
  240. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/interactivity_api_state_leak.py +0 -0
  241. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/js_framework_deep.py +0 -0
  242. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/js_libraries.py +0 -0
  243. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/js_supply_chain.py +0 -0
  244. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/jwt_audit.py +0 -0
  245. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/jwt_auth_plugin_audit.py +0 -0
  246. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/lead_gen_list_id_enum.py +0 -0
  247. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/login.py +0 -0
  248. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/login_redirect_http_hop.py +0 -0
  249. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/login_throttle.py +0 -0
  250. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/login_throttle_deep.py +0 -0
  251. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/login_timing.py +0 -0
  252. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/magecart_skimmer_patterns.py +0 -0
  253. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/mcp_endpoint_exposure.py +0 -0
  254. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/mfa_priv_account_audit.py +0 -0
  255. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/misc_injection_audit.py +0 -0
  256. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/mixed_content.py +0 -0
  257. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/mobile_app_endpoints.py +0 -0
  258. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/multisite.py +0 -0
  259. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/multisite_sso_key_reuse.py +0 -0
  260. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/nft_mint_pubapi.py +0 -0
  261. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/nonce_freshness.py +0 -0
  262. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/nosql_injection.py +0 -0
  263. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/oauth_oidc.py +0 -0
  264. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/oauth_redirect.py +0 -0
  265. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/oauth_redirect_misconfig.py +0 -0
  266. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/object_cache_dropin.py +0 -0
  267. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/open_redirect.py +0 -0
  268. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/open_registration.py +0 -0
  269. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/openapi_scanner.py +0 -0
  270. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/origin_ip_discovery.py +0 -0
  271. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/osint_enrich.py +0 -0
  272. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/package_lock_audit.py +0 -0
  273. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/page_builder_cve.py +0 -0
  274. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/path_bypass.py +0 -0
  275. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/path_traversal.py +0 -0
  276. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/payment_commerce_deep.py +0 -0
  277. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/payment_gateway_test_keys.py +0 -0
  278. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/perf_budget.py +0 -0
  279. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/perf_of_target.py +0 -0
  280. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/permissions_policy.py +0 -0
  281. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/php_eol.py +0 -0
  282. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/phpinfo_dangerous_directives.py +0 -0
  283. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/plugin_archive_fuzz.py +0 -0
  284. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/plugin_cemetery.py +0 -0
  285. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/plugin_cves.py +0 -0
  286. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/plugin_hash_fingerprint.py +0 -0
  287. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/plugin_install_rest_race.py +0 -0
  288. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/plugin_route_fuzz.py +0 -0
  289. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/plugin_specific_audit.py +0 -0
  290. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/plugin_typosquat_detection.py +0 -0
  291. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/plugins.py +0 -0
  292. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/postmeta_stored_xss_scan.py +0 -0
  293. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/premium_license_leak.py +0 -0
  294. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/privacy_inventory.py +0 -0
  295. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/prototype_pollution.py +0 -0
  296. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/pwa_service_worker_cache.py +0 -0
  297. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/race_condition.py +0 -0
  298. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/redirect_chain.py +0 -0
  299. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/rest_api.py +0 -0
  300. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/rest_app_passwords_enum.py +0 -0
  301. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/rest_fields_dos.py +0 -0
  302. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/rest_link_header.py +0 -0
  303. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/rest_namespace_leak.py +0 -0
  304. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/rest_permission_audit.py +0 -0
  305. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/rest_schema_field_leak.py +0 -0
  306. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/robots_sitemap.py +0 -0
  307. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/rum_beacons.py +0 -0
  308. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/s3_bucket_discovery.py +0 -0
  309. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/saml_xsw.py +0 -0
  310. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/search_highlight_xss.py +0 -0
  311. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/secret_leak.py +0 -0
  312. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/security_txt.py +0 -0
  313. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/sendmail_injection.py +0 -0
  314. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/server_timing.py +0 -0
  315. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/service_exposure.py +0 -0
  316. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/service_worker_scope_hijack.py +0 -0
  317. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/session_fixation.py +0 -0
  318. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/sitemap_cve_probe.py +0 -0
  319. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/smuggling_probe.py +0 -0
  320. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/solidity_abi_leak.py +0 -0
  321. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/source_maps.py +0 -0
  322. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/speculation_rules_audit.py +0 -0
  323. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/spider_crawl.py +0 -0
  324. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/sqli.py +0 -0
  325. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/sri_audit.py +0 -0
  326. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/sri_pwa_misc.py +0 -0
  327. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/ssrf.py +0 -0
  328. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/ssti.py +0 -0
  329. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/stripe_webhook_audit.py +0 -0
  330. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/tailwind_css_comment_leak.py +0 -0
  331. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/theme_cves.py +0 -0
  332. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/theme_json_font_ssrf.py +0 -0
  333. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/themes.py +0 -0
  334. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/timthumb.py +0 -0
  335. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/tls_modern.py +0 -0
  336. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/translation_plugin_key_leak.py +0 -0
  337. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/trellis_yaml_audit.py +0 -0
  338. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/turnstile_sitekey_reuse.py +0 -0
  339. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/upload_bypass_deep.py +0 -0
  340. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/upload_path_predictable.py +0 -0
  341. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/uploads_year_listing.py +0 -0
  342. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/users.py +0 -0
  343. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/users_deep.py +0 -0
  344. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/users_me_capability_leak.py +0 -0
  345. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/vendor_backdoor_patterns.py +0 -0
  346. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/vercel_preview_url_leak.py +0 -0
  347. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/waf.py +0 -0
  348. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/waf_brand_deep.py +0 -0
  349. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/waf_bypass_probe.py +0 -0
  350. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/waf_lockout_guard.py +0 -0
  351. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/waf_ruleset.py +0 -0
  352. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/wc_api_key_escalation.py +0 -0
  353. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/web3_wallet_connector_audit.py +0 -0
  354. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/webdav.py +0 -0
  355. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/webhook_signing_secrets.py +0 -0
  356. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/webhook_url_fingerprint.py +0 -0
  357. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/webhooks.py +0 -0
  358. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/websocket_fuzz.py +0 -0
  359. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/well_known.py +0 -0
  360. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/woo_blocks_checkout_drift.py +0 -0
  361. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/woo_subscriptions_renewal_race.py +0 -0
  362. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/woocommerce_audit.py +0 -0
  363. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/woocommerce_deep.py +0 -0
  364. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/woocommerce_order_idor.py +0 -0
  365. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/woocommerce_storefront.py +0 -0
  366. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/wp_builder_audit.py +0 -0
  367. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/wp_cli_http_exposure.py +0 -0
  368. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/wp_cli_inject.py +0 -0
  369. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/wp_commerce_alt_audit.py +0 -0
  370. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/wp_cron_cpu.py +0 -0
  371. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/wp_cron_disabled.py +0 -0
  372. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/wp_cron_dos.py +0 -0
  373. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/wp_debug_display_via_rest.py +0 -0
  374. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/wp_engine_misconfig.py +0 -0
  375. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/wp_fork_detection.py +0 -0
  376. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/wp_form_audit.py +0 -0
  377. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/wp_mail_smtp_site_health_leak.py +0 -0
  378. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/wp_membership_lms_audit.py +0 -0
  379. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/wp_multisite_deep.py +0 -0
  380. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/wp_playground_sqlite.py +0 -0
  381. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/wp_plugin_ecosystem_audit.py +0 -0
  382. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/wp_query_sqli.py +0 -0
  383. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/wp_rest_methods.py +0 -0
  384. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/wp_salts_age.py +0 -0
  385. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/wpconfig_hardening_audit.py +0 -0
  386. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/wpcron_suspicious_jobs.py +0 -0
  387. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/wpgraphql.py +0 -0
  388. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/xmlrpc_amplification.py +0 -0
  389. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/xmlrpc_deep.py +0 -0
  390. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/xmlrpc_method_brute.py +0 -0
  391. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/xss_dom_sinks.py +0 -0
  392. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/xss_reflected.py +0 -0
  393. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/xxe_upload.py +0 -0
  394. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/yaml_templates.py +0 -0
  395. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/yaml_workflows.py +0 -0
  396. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/yarn_pnpm_lock_audit.py +0 -0
  397. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/cli_extras.py +0 -0
  398. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/completion.py +0 -0
  399. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/confidence.py +0 -0
  400. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/config.py +0 -0
  401. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/console_live.py +0 -0
  402. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/continuous_monitor.py +0 -0
  403. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/crash_submit.py +0 -0
  404. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/creds_vault.py +0 -0
  405. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/daemon/__init__.py +0 -0
  406. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/daemon/webhook_v2.py +0 -0
  407. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/data/common_paths.txt +0 -0
  408. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/data/compliance_extra.json +0 -0
  409. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/data/compliance_v2.json +0 -0
  410. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/data/dashboard.html.j2 +0 -0
  411. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/data/datadog-dashboard.json +0 -0
  412. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/data/exploit_playbook.json +0 -0
  413. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/data/exploit_signatures.json +0 -0
  414. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/data/known_paths.txt +0 -0
  415. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/data/marketplace.json +0 -0
  416. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/data/newrelic-dashboard.json +0 -0
  417. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/data/openapi-scan-report.json +0 -0
  418. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/data/payloads.json +0 -0
  419. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/data/plugin_cves.json +0 -0
  420. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/data/plugin_file_hashes.json +0 -0
  421. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/data/quick_fixes.json +0 -0
  422. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/data/references.json +0 -0
  423. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/data/remediation_videos.json +0 -0
  424. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/data/report.schema.json +0 -0
  425. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/data/security_tutorial.json +0 -0
  426. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/db.py +0 -0
  427. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/demo.py +0 -0
  428. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/diff.py +0 -0
  429. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/edu_v27.py +0 -0
  430. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/education.py +0 -0
  431. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/enterprise/__init__.py +0 -0
  432. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/enterprise/billing_stub.py +0 -0
  433. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/enterprise/multi_tenant.py +0 -0
  434. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/enterprise/quota.py +0 -0
  435. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/eta.py +0 -0
  436. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/fun/__init__.py +0 -0
  437. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/fun/bingo_card.py +0 -0
  438. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/gh_check_run.py +0 -0
  439. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/gui_payloads.py +0 -0
  440. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/gui_v27_extras.py +0 -0
  441. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/gui_windows.py +0 -0
  442. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/har_replay.py +0 -0
  443. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/hardware_keys.py +0 -0
  444. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/heatmap.py +0 -0
  445. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/history.py +0 -0
  446. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/i18n.py +0 -0
  447. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/importers/__init__.py +0 -0
  448. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/importers/burp_zap.py +0 -0
  449. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/incremental/__init__.py +0 -0
  450. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/incremental/_legacy.py +0 -0
  451. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/incremental/diff_scan.py +0 -0
  452. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/incremental/smart_skip.py +0 -0
  453. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/integrations/__init__.py +0 -0
  454. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/integrations/cisa_kev.py +0 -0
  455. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/integrations/epss.py +0 -0
  456. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/integrations/github_issues.py +0 -0
  457. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/integrations/osint.py +0 -0
  458. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/integrations/sucuri_sitecheck.py +0 -0
  459. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/integrations/threat_intel.py +0 -0
  460. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/integrations/ticketing.py +0 -0
  461. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/integrations/tor_proxy.py +0 -0
  462. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/integrations/virustotal.py +0 -0
  463. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/integrations/webhooks_chat.py +0 -0
  464. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/interactsh.py +0 -0
  465. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/issue_push.py +0 -0
  466. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/js_plugin.py +0 -0
  467. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/kev.py +0 -0
  468. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/licensing.py +0 -0
  469. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/log.py +0 -0
  470. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/marketplace.py +0 -0
  471. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/marketplace_v27.py +0 -0
  472. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/mobile_app_discovery.py +0 -0
  473. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/models.py +0 -0
  474. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/monitors.py +0 -0
  475. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/notify.py +0 -0
  476. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/observability.py +0 -0
  477. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/password_audit.py +0 -0
  478. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/payloads.py +0 -0
  479. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/perf/connection_pool.py +0 -0
  480. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/perf/parallel_sites.py +0 -0
  481. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/perf_v27.py +0 -0
  482. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/playbook.py +0 -0
  483. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/policy.py +0 -0
  484. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/pr_inspector.py +0 -0
  485. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/prove.py +0 -0
  486. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/py.typed +0 -0
  487. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/recommend.py +0 -0
  488. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/reference_diff.py +0 -0
  489. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/region_egress.py +0 -0
  490. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/remediation_videos.py +0 -0
  491. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/report_query.py +0 -0
  492. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/reporters/__init__.py +0 -0
  493. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/reporters/attestation.py +0 -0
  494. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/reporters/auditor_pdf.py +0 -0
  495. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/reporters/badge_svg.py +0 -0
  496. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/reporters/board_one_pager.py +0 -0
  497. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/reporters/bounty_format.py +0 -0
  498. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/reporters/burp_export.py +0 -0
  499. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/reporters/comparison_two_sites.py +0 -0
  500. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/reporters/compliance_attestation.py +0 -0
  501. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/reporters/csv_out.py +0 -0
  502. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/reporters/d3fend_mapping.py +0 -0
  503. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/reporters/dashboard.py +0 -0
  504. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/reporters/diff_agency.py +0 -0
  505. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/reporters/diff_viewer.py +0 -0
  506. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/reporters/docx_report.py +0 -0
  507. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/reporters/eli5_toggle.py +0 -0
  508. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/reporters/exec_pdf.py +0 -0
  509. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/reporters/executive_pack.py +0 -0
  510. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/reporters/executive_tldr.py +0 -0
  511. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/reporters/finding_heatmap.py +0 -0
  512. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/reporters/gdpr_dsr_report.py +0 -0
  513. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/reporters/html.py +0 -0
  514. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/reporters/issue_export.py +0 -0
  515. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/reporters/live_sync.py +0 -0
  516. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/reporters/org_dashboard.py +0 -0
  517. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/reporters/pdf_custom_branding.py +0 -0
  518. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/reporters/public_page.py +0 -0
  519. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/reporters/risk_forecast.py +0 -0
  520. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/reporters/share_link.py +0 -0
  521. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/reporters/snapshot_compare.py +0 -0
  522. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/reporters/translated_summary.py +0 -0
  523. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/reporters/trend_over_time.py +0 -0
  524. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/reporters/user_template.py +0 -0
  525. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/reporters/vex_export.py +0 -0
  526. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/reporters/xlsx_out.py +0 -0
  527. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/reporters/xlsx_pivot.py +0 -0
  528. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/risk.py +0 -0
  529. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/risk_weights.py +0 -0
  530. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/sbom.py +0 -0
  531. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/scan_zip.py +0 -0
  532. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/scanner.py +0 -0
  533. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/scheduler.py +0 -0
  534. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/siem.py +0 -0
  535. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/sites.py +0 -0
  536. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/sla.py +0 -0
  537. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/slack_app.py +0 -0
  538. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/spider.py +0 -0
  539. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/ssh_audit.py +0 -0
  540. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/tags.py +0 -0
  541. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/template_engine.py +0 -0
  542. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/template_signature.py +0 -0
  543. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/threat_intel_v2.py +0 -0
  544. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/tray.py +0 -0
  545. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/trust_v27.py +0 -0
  546. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/turbo_engine.py +0 -0
  547. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/ua_rotation.py +0 -0
  548. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/ux_extras.py +0 -0
  549. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/waf_rules.py +0 -0
  550. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/watchers.py +0 -0
  551. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/workflow.py +0 -0
  552. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan.egg-info/dependency_links.txt +0 -0
  553. {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: wpsecscan
3
- Version: 2.7.3
3
+ Version: 2.8.0
4
4
  Summary: Defensive WordPress security scanner. 200+ checks, 8-source nightly CVE aggregator, AI-assisted remediation (BYO key), 15 compliance frameworks (OWASP/PCI/NIST/ISO/HIPAA/SOC2/HITRUST/CMMC), Sigstore-signed releases with SLSA L3 provenance, 10 threat-intel feeds (KEV/EPSS/Exploit-DB/ATT&CK/STIX/MISP/OTX/GreyNoise), continuous monitors, consent-gated exploit verification, multi-tenant RBAC/SSO/audit-log enterprise mode, 12 report formats. Authorized testing only.
5
5
  Author-email: Bryan <bryaninbangkok@gmail.com>
6
6
  License: GNU AFFERO GENERAL PUBLIC LICENSE
@@ -708,6 +708,13 @@ Requires-Dist: Pillow<12,>=10; extra == "ui"
708
708
  Requires-Dist: pystray<0.20,>=0.19; extra == "ui"
709
709
  Provides-Extra: security
710
710
  Requires-Dist: defusedxml<0.8,>=0.7; extra == "security"
711
+ Provides-Extra: aws
712
+ Requires-Dist: boto3<2,>=1.34; extra == "aws"
713
+ Provides-Extra: tts
714
+ Requires-Dist: gTTS<3,>=2.5; extra == "tts"
715
+ Requires-Dist: pyttsx3<3,>=2.90; extra == "tts"
716
+ Provides-Extra: push
717
+ Requires-Dist: pywebpush<3,>=2.0; extra == "push"
711
718
  Provides-Extra: all
712
719
  Requires-Dist: reportlab<5,>=4.0; extra == "all"
713
720
  Requires-Dist: playwright<2,>=1.40; extra == "all"
@@ -718,8 +725,12 @@ Requires-Dist: Pillow<12,>=10; extra == "all"
718
725
  Requires-Dist: pystray<0.20,>=0.19; extra == "all"
719
726
  Requires-Dist: keyring<26,>=24; extra == "all"
720
727
  Requires-Dist: defusedxml<0.8,>=0.7; extra == "all"
728
+ Requires-Dist: boto3<2,>=1.34; extra == "all"
729
+ Requires-Dist: gTTS<3,>=2.5; extra == "all"
730
+ Requires-Dist: pyttsx3<3,>=2.90; extra == "all"
731
+ Requires-Dist: pywebpush<3,>=2.0; extra == "all"
721
732
  Provides-Extra: test
722
- Requires-Dist: pytest>=7.4; extra == "test"
733
+ Requires-Dist: pytest<9,>=7.4; extra == "test"
723
734
  Dynamic: license-file
724
735
 
725
736
  # WPSecScan
@@ -1,10 +1,14 @@
1
1
  [build-system]
2
- requires = ["setuptools>=68", "wheel"]
2
+ # T4 (v2.8.0) — upper bounds on build-system deps per the v2.7.3
3
+ # Agent F F6 finding. A compromised `setuptools>=N` major release on
4
+ # PyPI would run arbitrary code at build time in every `pip install`
5
+ # from source; pinning bounds the supply-chain blast radius.
6
+ requires = ["setuptools>=68,<82", "wheel<1"]
3
7
  build-backend = "setuptools.build_meta"
4
8
 
5
9
  [project]
6
10
  name = "wpsecscan"
7
- version = "2.7.3"
11
+ version = "2.8.0"
8
12
  description = "Defensive WordPress security scanner. 200+ checks, 8-source nightly CVE aggregator, AI-assisted remediation (BYO key), 15 compliance frameworks (OWASP/PCI/NIST/ISO/HIPAA/SOC2/HITRUST/CMMC), Sigstore-signed releases with SLSA L3 provenance, 10 threat-intel feeds (KEV/EPSS/Exploit-DB/ATT&CK/STIX/MISP/OTX/GreyNoise), continuous monitors, consent-gated exploit verification, multi-tenant RBAC/SSO/audit-log enterprise mode, 12 report formats. Authorized testing only."
9
13
  readme = "README.md"
10
14
  requires-python = ">=3.10"
@@ -69,6 +73,14 @@ ui = ["Pillow>=10,<12", "pystray>=0.19,<0.20"]
69
73
  # entity-expansion DoS on hostile XML reports. Stdlib ElementTree falls
70
74
  # back with a stderr warning when this isn't installed.
71
75
  security = ["defusedxml>=0.7,<0.8"]
76
+ # T4 (v2.8.0) — explicit extras for the optional integrations whose
77
+ # imports were undeclared in pyproject (per v2.7.1 audit F-prep).
78
+ # `pip install 'wpsecscan[aws]'` etc. now installs the right deps.
79
+ # Lazy-import sites in integrations_v27 / mobile_v27 / edu_v27 keep
80
+ # wpsecscan importable without these.
81
+ aws = ["boto3>=1.34,<2"] # integrations_v27.push_aws_sechub
82
+ tts = ["gTTS>=2.5,<3", "pyttsx3>=2.90,<3"] # edu_v27.cmd_audio_summary
83
+ push = ["pywebpush>=2.0,<3"] # mobile_v27.web_push_send
72
84
  # Everything optional in one install
73
85
  all = [
74
86
  "reportlab>=4.0,<5",
@@ -80,12 +92,22 @@ all = [
80
92
  "pystray>=0.19,<0.20",
81
93
  "keyring>=24,<26",
82
94
  "defusedxml>=0.7,<0.8",
95
+ # T4 (v2.8.0)
96
+ "boto3>=1.34,<2",
97
+ "gTTS>=2.5,<3",
98
+ "pyttsx3>=2.90,<3",
99
+ "pywebpush>=2.0,<3",
83
100
  ]
84
- # Test deps (also installed by CI)
85
- test = ["pytest>=7.4"]
101
+ # Test deps (also installed by CI). T4 (v2.8.0) — upper bound added
102
+ # per the v2.7.3 Agent F F5 finding (pre-fix `>=7.4` could pull a
103
+ # breaking major into CI).
104
+ test = ["pytest>=7.4,<9"]
86
105
 
87
106
  [project.scripts]
88
107
  wpsecscan = "wpsecscan.__main__:main"
108
+ # U12 (v2.8.0) — short alias. Daily power-users typed `wpsecscan` 50+
109
+ # times per day; `wpsec` is a 4-keystroke save.
110
+ wpsec = "wpsecscan.__main__:main"
89
111
 
90
112
  [project.gui-scripts]
91
113
  wpsecscan-gui = "wpsecscan.gui:main"
@@ -0,0 +1,157 @@
1
+ """Coverage for wpsecscan/edu_v27.py.
2
+
3
+ Pins the cmd_learn topic dispatcher, translate_report_text no-op
4
+ fallbacks, link_glossary_terms regex coverage, confidence_explanation
5
+ lookup, plain_language fallback path, and cmd_audio_summary help-out.
6
+ """
7
+ from __future__ import annotations
8
+
9
+ import sys
10
+ from unittest.mock import patch
11
+
12
+ import pytest
13
+
14
+ from wpsecscan import edu_v27
15
+
16
+
17
+ # ---------------------------------------------------------------------------
18
+ # J116 — cmd_learn
19
+ # ---------------------------------------------------------------------------
20
+
21
+ def test_cmd_learn_no_args_lists_topics(capsys):
22
+ edu_v27.cmd_learn([])
23
+ out = capsys.readouterr().out
24
+ assert "WPSecScan — learn mode" in out
25
+ # Every topic id should appear in the listing.
26
+ for topic in edu_v27._LEARN_TOPICS:
27
+ assert topic in out
28
+
29
+
30
+ def test_cmd_learn_known_topic_prints_body(capsys):
31
+ edu_v27.cmd_learn(["csp"])
32
+ out = capsys.readouterr().out
33
+ assert "Content-Security-Policy" in out
34
+ assert "CSP" in out
35
+
36
+
37
+ def test_cmd_learn_unknown_topic_exits_64():
38
+ with pytest.raises(SystemExit) as exc:
39
+ edu_v27.cmd_learn(["bogus-topic"])
40
+ assert exc.value.code == 64
41
+
42
+
43
+ # ---------------------------------------------------------------------------
44
+ # J117 — translate_report_text
45
+ # ---------------------------------------------------------------------------
46
+
47
+ def test_translate_report_text_empty_returns_empty():
48
+ assert edu_v27.translate_report_text("", "ja") == ""
49
+
50
+
51
+ def test_translate_report_text_english_passthrough():
52
+ assert edu_v27.translate_report_text("hello", "en") == "hello"
53
+
54
+
55
+ def test_translate_report_text_no_ai_backend_passthrough():
56
+ """When ai_assist exists but isn't configured (no API key), the
57
+ helper must return the input verbatim — never silently drop text."""
58
+ with patch("wpsecscan.ai_assist.is_configured", return_value=False):
59
+ assert edu_v27.translate_report_text("hola", "ja") == "hola"
60
+
61
+
62
+ # ---------------------------------------------------------------------------
63
+ # J118 — cmd_audio_summary
64
+ # ---------------------------------------------------------------------------
65
+
66
+ def test_cmd_audio_summary_no_args_exits_64(capsys):
67
+ with pytest.raises(SystemExit) as exc:
68
+ edu_v27.cmd_audio_summary([])
69
+ assert exc.value.code == 64
70
+ assert "wpsecscan audio-summary" in capsys.readouterr().err
71
+
72
+
73
+ def test_cmd_audio_summary_help_exits_64(capsys):
74
+ with pytest.raises(SystemExit) as exc:
75
+ edu_v27.cmd_audio_summary(["--help"])
76
+ assert exc.value.code == 64
77
+
78
+
79
+ def test_cmd_audio_summary_no_saved_scan_exits_2(monkeypatch, tmp_path, capsys):
80
+ """When snapshot_history returns [] for the target, the command
81
+ must surface 'no saved scan' and exit 2 — not try to TTS nothing."""
82
+ monkeypatch.setenv("WPSECSCAN_HOME", str(tmp_path))
83
+ with patch("wpsecscan.history.snapshot_history", return_value=[]):
84
+ with pytest.raises(SystemExit) as exc:
85
+ edu_v27.cmd_audio_summary(["https://example.com"])
86
+ assert exc.value.code == 2
87
+ assert "no saved scan" in capsys.readouterr().err
88
+
89
+
90
+ # ---------------------------------------------------------------------------
91
+ # J119 — plain_language
92
+ # ---------------------------------------------------------------------------
93
+
94
+ class _StubFinding:
95
+ title = "stub-title"
96
+
97
+
98
+ def test_plain_language_ai_unavailable_falls_back_to_title():
99
+ """When ai_assist is missing or raises, the helper must return the
100
+ raw finding title — silent-fail must NOT eat the message."""
101
+ with patch("wpsecscan.ai_assist.client_summarize_finding",
102
+ side_effect=AttributeError("not configured")):
103
+ assert edu_v27.plain_language(_StubFinding()) == "stub-title"
104
+
105
+
106
+ # ---------------------------------------------------------------------------
107
+ # J120 — link_glossary_terms
108
+ # ---------------------------------------------------------------------------
109
+
110
+ def test_link_glossary_terms_wraps_cve():
111
+ out = edu_v27.link_glossary_terms("see CVE-2024-1234 for details")
112
+ assert "<a href=" in out
113
+ assert "nvd.nist.gov/vuln/detail/CVE-2024-1234" in out
114
+ assert ">CVE-2024-1234</a>" in out
115
+
116
+
117
+ def test_link_glossary_terms_wraps_owasp():
118
+ out = edu_v27.link_glossary_terms("ranked A01:2021 in the top-10")
119
+ assert "owasp.org/Top10" in out
120
+ assert "A01:2021" in out
121
+
122
+
123
+ def test_link_glossary_terms_wraps_attack_technique():
124
+ out = edu_v27.link_glossary_terms("uses T1059.001 PowerShell abuse")
125
+ assert "attack.mitre.org/techniques/T1059.001" in out
126
+
127
+
128
+ def test_link_glossary_terms_wraps_d3fend():
129
+ out = edu_v27.link_glossary_terms("mitigated by D3-DA defenses")
130
+ assert "d3fend.mitre.org" in out
131
+ assert "D3-DA" in out
132
+
133
+
134
+ def test_link_glossary_terms_leaves_plain_text_alone():
135
+ plain = "just a plain string with no tokens"
136
+ assert edu_v27.link_glossary_terms(plain) == plain
137
+
138
+
139
+ # ---------------------------------------------------------------------------
140
+ # J121 — confidence_explanation
141
+ # ---------------------------------------------------------------------------
142
+
143
+ @pytest.mark.parametrize("level", ["low", "medium", "high"])
144
+ def test_confidence_explanation_known_levels(level):
145
+ text = edu_v27.confidence_explanation(level)
146
+ assert text # non-empty
147
+ assert level in text.lower()
148
+
149
+
150
+ def test_confidence_explanation_normalises_case():
151
+ assert edu_v27.confidence_explanation("HIGH") == edu_v27.confidence_explanation("high")
152
+
153
+
154
+ def test_confidence_explanation_unknown_returns_empty():
155
+ assert edu_v27.confidence_explanation("unknown") == ""
156
+ assert edu_v27.confidence_explanation("") == ""
157
+ assert edu_v27.confidence_explanation(None) == "" # type: ignore[arg-type]
@@ -0,0 +1,203 @@
1
+ """Coverage for wpsecscan/perf_v27.py.
2
+
3
+ Pins the v2.7.1-era B1 worker URL-validation guard, the etag cache
4
+ helpers, the per-check timeout env-var resolution, the prewarm_dns
5
+ no-op-on-failure contract, and the parallel scan-zip walker.
6
+
7
+ Note: payload strings below intentionally use string-concatenation
8
+ splits to avoid Windows Defender heuristics that would otherwise quarantine
9
+ this test file (e.g. the literal "rm -rf /" or "eval($_POST[...])" trip
10
+ ML-based malware classifiers).
11
+ """
12
+ from __future__ import annotations
13
+
14
+ import asyncio
15
+ from unittest.mock import patch
16
+
17
+ import pytest
18
+
19
+ from wpsecscan import perf_v27
20
+
21
+
22
+ # ---------------------------------------------------------------------------
23
+ # I110 - cmd_worker URL-validation guard (B1 regression)
24
+ # ---------------------------------------------------------------------------
25
+
26
+ def test_cmd_worker_help_returns_without_error(capsys):
27
+ perf_v27.cmd_worker(["--help"])
28
+ captured = capsys.readouterr()
29
+ assert "wpsecscan worker" in captured.err
30
+
31
+
32
+ def test_cmd_worker_refuses_non_url_queue_entries(monkeypatch, tmp_path, capsys):
33
+ # B5-adjacent (v2.8.0) — must inherit BaseException, not Exception:
34
+ # cmd_worker's `except Exception` would catch _Stop as a "redis
35
+ # error" and `continue`, infinite-looping in the test. KeyboardInterrupt
36
+ # is the conventional escape from such loops.
37
+ class _Stop(KeyboardInterrupt):
38
+ pass
39
+
40
+ bad_payloads = [
41
+ b"--config /etc/somefile",
42
+ b"file:///etc/somefile",
43
+ b"-flag-injection-attempt",
44
+ ]
45
+
46
+ class _StubPipe:
47
+ def __init__(self):
48
+ self._payloads = list(bad_payloads)
49
+
50
+ def brpop(self, queue, timeout=0): # noqa: ARG002
51
+ if self._payloads:
52
+ return ("k", self._payloads.pop(0))
53
+ raise _Stop()
54
+
55
+ class _StubRedisModule:
56
+ @staticmethod
57
+ def from_url(url): # noqa: ARG004
58
+ return _StubPipe()
59
+
60
+ monkeypatch.setitem(__import__("sys").modules, "redis", _StubRedisModule)
61
+ called = []
62
+ with patch("subprocess.run", side_effect=lambda *a, **kw: called.append(a)):
63
+ try:
64
+ perf_v27.cmd_worker(["--queue", "wpsecscan:urls", "--out", str(tmp_path)])
65
+ except _Stop:
66
+ pass
67
+ captured = capsys.readouterr()
68
+ assert "refusing non-URL queue entry" in captured.err
69
+ assert called == [], "subprocess.run must not be called for non-URL targets"
70
+
71
+
72
+ def test_cmd_worker_empty_target_skipped(monkeypatch, tmp_path):
73
+ # B5-adjacent (v2.8.0) — must inherit BaseException, not Exception:
74
+ # cmd_worker's `except Exception` would catch _Stop as a "redis
75
+ # error" and `continue`, infinite-looping in the test. KeyboardInterrupt
76
+ # is the conventional escape from such loops.
77
+ class _Stop(KeyboardInterrupt):
78
+ pass
79
+
80
+ class _StubPipe:
81
+ def __init__(self):
82
+ self.calls = 0
83
+
84
+ def brpop(self, queue, timeout=0): # noqa: ARG002
85
+ self.calls += 1
86
+ if self.calls == 1:
87
+ return ("k", b" ")
88
+ raise _Stop()
89
+
90
+ pipe = _StubPipe()
91
+
92
+ class _StubRedisModule:
93
+ @staticmethod
94
+ def from_url(url): # noqa: ARG004
95
+ return pipe
96
+
97
+ monkeypatch.setitem(__import__("sys").modules, "redis", _StubRedisModule)
98
+ called = []
99
+ with patch("subprocess.run", side_effect=lambda *a, **kw: called.append(a)):
100
+ with pytest.raises(_Stop):
101
+ perf_v27.cmd_worker(["--out", str(tmp_path)])
102
+ assert called == []
103
+
104
+
105
+ # ---------------------------------------------------------------------------
106
+ # I111 - etag cache get/set
107
+ # ---------------------------------------------------------------------------
108
+
109
+ def test_etag_get_returns_none_for_missing_file(monkeypatch, tmp_path):
110
+ monkeypatch.setenv("WPSECSCAN_HOME", str(tmp_path))
111
+ assert perf_v27.etag_get("https://example.com") is None
112
+
113
+
114
+ def test_etag_set_then_get_roundtrip(monkeypatch, tmp_path):
115
+ monkeypatch.setenv("WPSECSCAN_HOME", str(tmp_path))
116
+ perf_v27.etag_set("https://example.com", "etag-abc",
117
+ "Wed, 21 Oct 2026 07:28:00 GMT")
118
+ got = perf_v27.etag_get("https://example.com")
119
+ assert got == ("etag-abc", "Wed, 21 Oct 2026 07:28:00 GMT")
120
+
121
+
122
+ def test_etag_get_handles_corrupt_db(monkeypatch, tmp_path):
123
+ monkeypatch.setenv("WPSECSCAN_HOME", str(tmp_path))
124
+ (tmp_path / "etag-cache.json").write_text("not-json")
125
+ assert perf_v27.etag_get("https://example.com") is None
126
+
127
+
128
+ def test_etag_set_handles_corrupt_db(monkeypatch, tmp_path):
129
+ monkeypatch.setenv("WPSECSCAN_HOME", str(tmp_path))
130
+ (tmp_path / "etag-cache.json").write_text("not-json")
131
+ perf_v27.etag_set("https://example.com", "e", "")
132
+ assert perf_v27.etag_get("https://example.com") == ("e", "")
133
+
134
+
135
+ # ---------------------------------------------------------------------------
136
+ # I112 - timeout_for
137
+ # ---------------------------------------------------------------------------
138
+
139
+ def test_timeout_for_specific_env_wins(monkeypatch):
140
+ monkeypatch.setenv("WPSECSCAN_CHECK_TIMEOUT_XMLRPC", "12.5")
141
+ monkeypatch.setenv("WPSECSCAN_DEFAULT_CHECK_TIMEOUT", "60")
142
+ assert perf_v27.timeout_for("xmlrpc") == 12.5
143
+
144
+
145
+ def test_timeout_for_falls_back_to_generic(monkeypatch):
146
+ monkeypatch.delenv("WPSECSCAN_CHECK_TIMEOUT_XMLRPC", raising=False)
147
+ monkeypatch.setenv("WPSECSCAN_DEFAULT_CHECK_TIMEOUT", "45")
148
+ assert perf_v27.timeout_for("xmlrpc") == 45.0
149
+
150
+
151
+ def test_timeout_for_default_when_no_env(monkeypatch):
152
+ monkeypatch.delenv("WPSECSCAN_CHECK_TIMEOUT_XMLRPC", raising=False)
153
+ monkeypatch.delenv("WPSECSCAN_DEFAULT_CHECK_TIMEOUT", raising=False)
154
+ assert perf_v27.timeout_for("xmlrpc") == 30.0
155
+ assert perf_v27.timeout_for("xmlrpc", default=5.0) == 5.0
156
+
157
+
158
+ def test_timeout_for_malformed_env_falls_through(monkeypatch):
159
+ monkeypatch.setenv("WPSECSCAN_CHECK_TIMEOUT_XMLRPC", "not-a-number")
160
+ monkeypatch.setenv("WPSECSCAN_DEFAULT_CHECK_TIMEOUT", "also-bad")
161
+ assert perf_v27.timeout_for("xmlrpc") == 30.0
162
+
163
+
164
+ # ---------------------------------------------------------------------------
165
+ # I114 - prewarm_dns
166
+ # ---------------------------------------------------------------------------
167
+
168
+ def test_prewarm_dns_empty_host_returns_false():
169
+ assert asyncio.run(perf_v27.prewarm_dns("")) is False
170
+
171
+
172
+ def test_prewarm_dns_handles_resolution_failure():
173
+ # `.invalid` is reserved (RFC 6761) and never resolves.
174
+ result = asyncio.run(perf_v27.prewarm_dns("this-host-cannot-exist.invalid"))
175
+ assert result is False
176
+
177
+
178
+ # ---------------------------------------------------------------------------
179
+ # I115 - scan_zip_parallel_paths
180
+ # ---------------------------------------------------------------------------
181
+
182
+ def test_scan_zip_parallel_paths_finds_matches(tmp_path):
183
+ import re
184
+ a = tmp_path / "a.txt"
185
+ b = tmp_path / "b.txt"
186
+ # Defender-safe substrings; we're testing the regex driver, not WordPress.
187
+ a.write_text("PATTERN_A here PATTERN_A again\n")
188
+ b.write_text("just plain text\n")
189
+ patterns = [re.compile(r"PATTERN_A"), re.compile(r"NEVER_MATCHES")]
190
+ hits = perf_v27.scan_zip_parallel_paths([a, b], patterns, workers=2)
191
+ paths = {h[0] for h in hits}
192
+ assert a in paths
193
+ assert b not in paths
194
+ assert any(h[1] == 0 for h in hits)
195
+ assert all(h[1] != 1 for h in hits)
196
+
197
+
198
+ def test_scan_zip_parallel_paths_skips_unreadable(tmp_path):
199
+ import re
200
+ nonexistent = tmp_path / "missing.txt"
201
+ patterns = [re.compile(r"anything")]
202
+ hits = perf_v27.scan_zip_parallel_paths([nonexistent], patterns, workers=1)
203
+ assert hits == []
@@ -82,10 +82,13 @@ def test_markdown_reporter_render():
82
82
  text = md.render(r)
83
83
  assert "# WPSecScan" in text
84
84
  assert "Risk score" in text
85
- # Triple-backtick fence; embedded ``` is sanitized with a zero-width space
86
- # so it can't terminate the fence early.
87
- assert "```" in text
88
- assert "`​``" in text # zero-width-space-broken sequence
85
+ # B40 (v2.8.0) — was: 3-backtick fence with ZWS hack. Now: 4-
86
+ # backtick fence (CommonMark allows any backtick run >= 3; closer
87
+ # must match length). Embedded literal ``` no longer needs escape.
88
+ assert "````" in text
89
+ # The literal embedded ``` from the evidence is preserved as-is
90
+ # (no zero-width-space mutation).
91
+ assert "```nested```" in text
89
92
 
90
93
 
91
94
  def test_markdown_reporter_top_n_keeps_highest_severities():
@@ -0,0 +1,146 @@
1
+ """Coverage for wpsecscan/trust_v27.py.
2
+
3
+ Pins build_provenance_graph shape, the third_party_audit_url env-var
4
+ contract, and set_deterministic_seed side-effects. The reproducible-
5
+ build verifier is exercised by patching subprocess.run; we don't
6
+ actually pip-download or rebuild a wheel in unit tests.
7
+ """
8
+ from __future__ import annotations
9
+
10
+ import os
11
+ import random
12
+ from unittest.mock import patch
13
+
14
+ import pytest
15
+
16
+ from wpsecscan import trust_v27
17
+ from wpsecscan.models import CheckResult, Finding, ScanReport
18
+
19
+
20
+ # ---------------------------------------------------------------------------
21
+ # K122 — reproducible_build_verify
22
+ # ---------------------------------------------------------------------------
23
+
24
+ def _fake_completed(returncode=0, stdout="", stderr=""):
25
+ class _R:
26
+ pass
27
+ r = _R()
28
+ r.returncode = returncode
29
+ r.stdout = stdout
30
+ r.stderr = stderr
31
+ return r
32
+
33
+
34
+ def test_reproducible_build_verify_pip_download_failure():
35
+ with patch("subprocess.run",
36
+ return_value=_fake_completed(returncode=1, stderr="network down")):
37
+ ok, msg = trust_v27.reproducible_build_verify("2.7.1")
38
+ assert ok is False
39
+ assert "pip download" in msg
40
+
41
+
42
+ def test_reproducible_build_verify_no_sdist_found(tmp_path, monkeypatch):
43
+ """pip download succeeds (returncode 0) but no sdist lands in the
44
+ work dir → must report 'no sdist found'."""
45
+ monkeypatch.setattr(
46
+ "tempfile.mkdtemp",
47
+ lambda **kw: str(tmp_path), # noqa: ARG005
48
+ )
49
+ with patch("subprocess.run", return_value=_fake_completed(returncode=0)):
50
+ ok, msg = trust_v27.reproducible_build_verify("2.7.1")
51
+ assert ok is False
52
+ assert "no sdist found" in msg
53
+
54
+
55
+ # ---------------------------------------------------------------------------
56
+ # K123 — build_provenance_graph
57
+ # ---------------------------------------------------------------------------
58
+
59
+ def _make_report() -> ScanReport:
60
+ f1 = Finding(severity="high", title="XSS in /search",
61
+ evidence="<script>", url="https://t/search",
62
+ extra={"http_method": "POST", "ai_anomaly": 0.92,
63
+ "kev_match": True, "fp_score": 0.05})
64
+ f2 = Finding(severity="medium", title="info-disclosure", evidence="x")
65
+ r1 = CheckResult(check_id="xss_reflected", check_name="Reflected XSS",
66
+ findings=[f1, f2])
67
+ return ScanReport(target="https://t", scanned_at="2026-05-27T00:00:00Z",
68
+ duration_ms=0, results=[r1])
69
+
70
+
71
+ def test_build_provenance_graph_shape():
72
+ rep = _make_report()
73
+ graph = trust_v27.build_provenance_graph(rep)
74
+ assert graph["target"] == "https://t"
75
+ assert graph["scanned_at"] == "2026-05-27T00:00:00Z"
76
+ assert isinstance(graph["lineage"], list)
77
+ assert len(graph["lineage"]) == 2 # two findings
78
+
79
+
80
+ def test_build_provenance_graph_preserves_per_finding_metadata():
81
+ rep = _make_report()
82
+ graph = trust_v27.build_provenance_graph(rep)
83
+ first = graph["lineage"][0]
84
+ assert first["finding_index"] == 0
85
+ assert first["check_id"] == "xss_reflected"
86
+ assert first["severity"] == "high"
87
+ assert first["produced_by_request"]["url"] == "https://t/search"
88
+ assert first["produced_by_request"]["method"] == "POST"
89
+ assert first["policy_applied"]["ai_anomaly"] == 0.92
90
+ assert first["policy_applied"]["kev_match"] is True
91
+ assert first["policy_applied"]["fp_score"] == 0.05
92
+
93
+
94
+ def test_build_provenance_graph_handles_missing_extra():
95
+ """Finding.extra defaults to {}; the helper must fall back to GET
96
+ and emit None for every policy field that wasn't supplied."""
97
+ rep = _make_report()
98
+ second = trust_v27.build_provenance_graph(rep)["lineage"][1]
99
+ assert second["produced_by_request"]["method"] == "GET"
100
+ assert second["produced_by_request"]["url"] == ""
101
+ assert second["policy_applied"]["ai_anomaly"] is None
102
+ assert second["policy_applied"]["kev_match"] is None
103
+
104
+
105
+ def test_build_provenance_graph_empty_report():
106
+ rep = ScanReport(target="https://t", scanned_at="now", duration_ms=0,
107
+ results=[])
108
+ graph = trust_v27.build_provenance_graph(rep)
109
+ assert graph["lineage"] == []
110
+
111
+
112
+ # ---------------------------------------------------------------------------
113
+ # K124 — third_party_audit_url
114
+ # ---------------------------------------------------------------------------
115
+
116
+ def test_third_party_audit_url_empty_by_default(monkeypatch):
117
+ monkeypatch.delenv("WPSECSCAN_AUDIT_URL", raising=False)
118
+ assert trust_v27.third_party_audit_url() == ""
119
+
120
+
121
+ def test_third_party_audit_url_env_override(monkeypatch):
122
+ monkeypatch.setenv("WPSECSCAN_AUDIT_URL", "https://example.com/audit.pdf")
123
+ assert trust_v27.third_party_audit_url() == "https://example.com/audit.pdf"
124
+
125
+
126
+ # ---------------------------------------------------------------------------
127
+ # K125 — set_deterministic_seed
128
+ # ---------------------------------------------------------------------------
129
+
130
+ def test_set_deterministic_seed_python_random_reproducible(monkeypatch):
131
+ trust_v27.set_deterministic_seed(42)
132
+ a = [random.random() for _ in range(5)]
133
+ trust_v27.set_deterministic_seed(42)
134
+ b = [random.random() for _ in range(5)]
135
+ assert a == b
136
+
137
+
138
+ def test_set_deterministic_seed_writes_env_var(monkeypatch):
139
+ monkeypatch.delenv("WPSECSCAN_DETERMINISTIC_SEED", raising=False)
140
+ trust_v27.set_deterministic_seed(1337)
141
+ assert os.environ["WPSECSCAN_DETERMINISTIC_SEED"] == "1337"
142
+
143
+
144
+ def test_set_deterministic_seed_default_is_1729(monkeypatch):
145
+ trust_v27.set_deterministic_seed()
146
+ assert os.environ["WPSECSCAN_DETERMINISTIC_SEED"] == "1729"