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.
- {wpsecscan-2.7.3/wpsecscan.egg-info → wpsecscan-2.8.0}/PKG-INFO +13 -2
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/pyproject.toml +26 -4
- wpsecscan-2.8.0/tests/test_edu_v27.py +157 -0
- wpsecscan-2.8.0/tests/test_perf_v27.py +203 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/tests/test_round_q.py +7 -4
- wpsecscan-2.8.0/tests/test_trust_v27.py +146 -0
- wpsecscan-2.8.0/tests/test_v280_critical_regressions.py +93 -0
- wpsecscan-2.8.0/tests/test_v280_wave2_regressions.py +261 -0
- wpsecscan-2.8.0/wpsecscan/__init__.py +1 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/__main__.py +54 -12
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/ai_assist.py +25 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/ai_safety.py +14 -21
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/api_server.py +101 -6
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/__init__.py +8 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/csp.py +25 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/csrf_nonce.py +8 -1
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/csv_export_csp.py +14 -4
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/email_security_deep.py +11 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/gdpr_dsr_endpoint_enum.py +9 -2
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/gutenberg_blocks.py +7 -1
- wpsecscan-2.8.0/wpsecscan/checks/headless_cors_lockdown.py +94 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/referenced_buckets.py +8 -3
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/server_stack_reveal.py +5 -1
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/subdomains.py +25 -3
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/tls_deep.py +39 -2
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/tls_headers.py +8 -2
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/tls_reneg_dos.py +12 -3
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/wallet_seed_phrase_leak.py +16 -2
- wpsecscan-2.8.0/wpsecscan/checks/wc_coupon_enum.py +116 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/websocket_audit.py +14 -4
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/daemon/_legacy.py +47 -6
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/data/check_tags.json +3 -1
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/data/compliance_map.json +10 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/data/report.html.j2 +70 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/gui.py +89 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/http.py +11 -1
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/integrations_v27.py +10 -1
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/mobile_api.py +15 -1
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/mobile_v27.py +49 -0
- wpsecscan-2.8.0/wpsecscan/perf/__init__.py +17 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/perf/_legacy.py +18 -29
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/reporters/console.py +4 -1
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/reporters/json_out.py +23 -1
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/reporters/markdown.py +11 -7
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/reporters/sarif.py +9 -3
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/workflow_cmds.py +11 -1
- {wpsecscan-2.7.3 → wpsecscan-2.8.0/wpsecscan.egg-info}/PKG-INFO +13 -2
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan.egg-info/SOURCES.txt +7 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan.egg-info/entry_points.txt +1 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan.egg-info/requires.txt +15 -1
- wpsecscan-2.7.3/wpsecscan/__init__.py +0 -1
- wpsecscan-2.7.3/wpsecscan/perf/__init__.py +0 -12
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/LICENSE +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/NOTICE +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/README.md +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/setup.cfg +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/tests/test_audit_fixes.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/tests/test_audit_round_r.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/tests/test_board_one_pager.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/tests/test_burp_zap_import.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/tests/test_cache.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/tests/test_checks.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/tests/test_confidence_eta_tags.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/tests/test_creds_vault_cli.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/tests/test_default_creds.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/tests/test_diff_agency.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/tests/test_gh_check_run.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/tests/test_global_sigs_regression.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/tests/test_integrations_graphql_escape.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/tests/test_login_throttle.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/tests/test_login_throttle_deep.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/tests/test_marketplace_install_url_guard.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/tests/test_mobile_api_traversal.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/tests/test_new_check_inventory.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/tests/test_new_checks.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/tests/test_new_checks_aggressive.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/tests/test_new_checks_quality.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/tests/test_notify.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/tests/test_password_audit.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/tests/test_payloads.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/tests/test_phase5.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/tests/test_playbook.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/tests/test_prove.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/tests/test_reference_diff.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/tests/test_reference_diff_traversal.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/tests/test_risk_score.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/tests/test_round_54.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/tests/test_round_55.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/tests/test_round_56_activity.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/tests/test_round_57.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/tests/test_round_58.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/tests/test_round_59.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/tests/test_round_60.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/tests/test_round_61.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/tests/test_round_62.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/tests/test_round_63.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/tests/test_round_64.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/tests/test_round_65.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/tests/test_scan_zip.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/tests/test_scheduler.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/tests/test_scheduler_cron_dow.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/tests/test_siem.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/tests/test_sla.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/tests/test_slack_app.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/tests/test_ssh_audit.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/tests/test_user_template.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/tests/test_v272_audit_log_constant_time.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/tests/test_v272_marketplace_sigstore_identity.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/tests/test_v272_wave2_regressions.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/tests/test_v272_wave3_regressions.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/tests/test_v272_wave4_regressions.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/tests/test_v273_critical_regressions.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/tests/test_v273_wave2_regressions.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/tests/test_v273_wave3_companion.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/tests/test_v273_wave5_audit_log_wired.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/_util.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/activity.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/ai_fp_predictor.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/ai_triage.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/ai_triage_ui.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/analytics.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/attack_checkpoint.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/attack_scripts.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/auth/__init__.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/auth/approval_workflow.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/auth/audit_log.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/auth/rbac.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/auth/sso_oidc.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/auth/sso_saml.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/auto_pr.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/auto_update.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/baseline.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/branding.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/bug_report.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/burp_import.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/cache.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/check_health.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/_template.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/a11y_deep.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/a11y_lite.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/a11y_wcag_aaa.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/abuseipdb_lookup.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/admin_ajax_brute_surface.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/admin_invite_link_scan.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/ai_agent_webhook_leak.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/ai_chatbot_endpoint_leak.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/ai_plugin_prompt_storage.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/ai_prompt_injection_passive.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/ajax_surface.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/algolia_elastic_frontend_keys.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/amp_transitional_redirect.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/app_passwords.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/app_passwords_stale_audit.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/auth_modernisation.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/authenticated.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/backup_exposure.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/backup_file_fuzz.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/block_bindings_exposure.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/block_style_variations_url.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/brand_monitor.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/bucket_shadow_takeover.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/cache_headers.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/cache_poisoning.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/cache_poisoning_v2.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/cdn_edge_audit.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/cloud_metadata_ssrf.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/cloudflare_origin_leak.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/companion_advanced.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/companion_v13.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/companion_v14.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/compliance_frameworks.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/composer_lock_audit.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/composer_npm_typosquat.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/cookie_consent.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/cookie_consent_desync.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/cookies.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/core_checksums.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/core_cves.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/core_tampering.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/core_version.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/cors.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/crlf_location_injection.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/crypto_agility.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/crypto_payment_callback_audit.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/cryptominer_js_injection.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/csp_report_endpoint.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/csrf_entropy.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/ct_log_recent_certs.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/ct_log_shadow_cert.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/db_admin_login_probe.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/db_trigger_audit.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/debug_leaks.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/debug_log_pii_sniff.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/default_creds.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/dev_params.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/directory_listing.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/dns_deep.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/dns_rebinding.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/dns_security.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/dns_templates.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/dom_xss_headless.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/email_obfuscation_audit.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/env_file_enum.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/error_pages.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/exposed_files.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/favicon_fingerprint.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/file_upload.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/font_library_api_ssrf.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/forced_browse.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/form_builder_upload_bypass.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/gdpr_dsr.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/git_dir_deep_scan.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/github_actions_workflow_leak.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/github_leak_search.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/graphql_dos.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/graphql_field_authz_deep.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/gtm_inventory.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/header_smuggling_case.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/headless_templates.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/headless_vercel_netlify_detect.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/headless_wp_audit.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/heartbeat_abuse.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/heartbeat_frontend.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/helm_compose_leak.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/hibp.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/honeypot_admin.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/host_header_validation.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/host_platform_detect.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/host_recon.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/hosting_platform_audit.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/hostname_collision.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/hpp.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/hsts_preload_eligibility.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/hsts_preload_mismatch.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/html_api_csp_nonce.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/http2_settings.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/http2_smuggling.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/http3_fingerprint.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/http_methods.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/interactivity_api_state_leak.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/js_framework_deep.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/js_libraries.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/js_supply_chain.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/jwt_audit.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/jwt_auth_plugin_audit.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/lead_gen_list_id_enum.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/login.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/login_redirect_http_hop.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/login_throttle.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/login_throttle_deep.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/login_timing.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/magecart_skimmer_patterns.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/mcp_endpoint_exposure.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/mfa_priv_account_audit.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/misc_injection_audit.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/mixed_content.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/mobile_app_endpoints.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/multisite.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/multisite_sso_key_reuse.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/nft_mint_pubapi.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/nonce_freshness.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/nosql_injection.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/oauth_oidc.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/oauth_redirect.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/oauth_redirect_misconfig.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/object_cache_dropin.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/open_redirect.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/open_registration.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/openapi_scanner.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/origin_ip_discovery.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/osint_enrich.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/package_lock_audit.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/page_builder_cve.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/path_bypass.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/path_traversal.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/payment_commerce_deep.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/payment_gateway_test_keys.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/perf_budget.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/perf_of_target.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/permissions_policy.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/php_eol.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/phpinfo_dangerous_directives.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/plugin_archive_fuzz.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/plugin_cemetery.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/plugin_cves.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/plugin_hash_fingerprint.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/plugin_install_rest_race.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/plugin_route_fuzz.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/plugin_specific_audit.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/plugin_typosquat_detection.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/plugins.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/postmeta_stored_xss_scan.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/premium_license_leak.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/privacy_inventory.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/prototype_pollution.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/pwa_service_worker_cache.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/race_condition.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/redirect_chain.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/rest_api.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/rest_app_passwords_enum.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/rest_fields_dos.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/rest_link_header.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/rest_namespace_leak.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/rest_permission_audit.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/rest_schema_field_leak.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/robots_sitemap.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/rum_beacons.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/s3_bucket_discovery.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/saml_xsw.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/search_highlight_xss.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/secret_leak.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/security_txt.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/sendmail_injection.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/server_timing.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/service_exposure.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/service_worker_scope_hijack.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/session_fixation.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/sitemap_cve_probe.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/smuggling_probe.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/solidity_abi_leak.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/source_maps.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/speculation_rules_audit.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/spider_crawl.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/sqli.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/sri_audit.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/sri_pwa_misc.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/ssrf.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/ssti.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/stripe_webhook_audit.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/tailwind_css_comment_leak.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/theme_cves.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/theme_json_font_ssrf.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/themes.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/timthumb.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/tls_modern.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/translation_plugin_key_leak.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/trellis_yaml_audit.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/turnstile_sitekey_reuse.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/upload_bypass_deep.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/upload_path_predictable.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/uploads_year_listing.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/users.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/users_deep.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/users_me_capability_leak.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/vendor_backdoor_patterns.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/vercel_preview_url_leak.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/waf.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/waf_brand_deep.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/waf_bypass_probe.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/waf_lockout_guard.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/waf_ruleset.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/wc_api_key_escalation.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/web3_wallet_connector_audit.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/webdav.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/webhook_signing_secrets.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/webhook_url_fingerprint.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/webhooks.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/websocket_fuzz.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/well_known.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/woo_blocks_checkout_drift.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/woo_subscriptions_renewal_race.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/woocommerce_audit.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/woocommerce_deep.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/woocommerce_order_idor.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/woocommerce_storefront.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/wp_builder_audit.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/wp_cli_http_exposure.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/wp_cli_inject.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/wp_commerce_alt_audit.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/wp_cron_cpu.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/wp_cron_disabled.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/wp_cron_dos.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/wp_debug_display_via_rest.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/wp_engine_misconfig.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/wp_fork_detection.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/wp_form_audit.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/wp_mail_smtp_site_health_leak.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/wp_membership_lms_audit.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/wp_multisite_deep.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/wp_playground_sqlite.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/wp_plugin_ecosystem_audit.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/wp_query_sqli.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/wp_rest_methods.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/wp_salts_age.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/wpconfig_hardening_audit.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/wpcron_suspicious_jobs.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/wpgraphql.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/xmlrpc_amplification.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/xmlrpc_deep.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/xmlrpc_method_brute.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/xss_dom_sinks.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/xss_reflected.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/xxe_upload.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/yaml_templates.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/yaml_workflows.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/checks/yarn_pnpm_lock_audit.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/cli_extras.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/completion.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/confidence.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/config.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/console_live.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/continuous_monitor.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/crash_submit.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/creds_vault.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/daemon/__init__.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/daemon/webhook_v2.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/data/common_paths.txt +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/data/compliance_extra.json +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/data/compliance_v2.json +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/data/dashboard.html.j2 +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/data/datadog-dashboard.json +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/data/exploit_playbook.json +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/data/exploit_signatures.json +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/data/known_paths.txt +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/data/marketplace.json +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/data/newrelic-dashboard.json +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/data/openapi-scan-report.json +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/data/payloads.json +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/data/plugin_cves.json +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/data/plugin_file_hashes.json +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/data/quick_fixes.json +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/data/references.json +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/data/remediation_videos.json +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/data/report.schema.json +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/data/security_tutorial.json +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/db.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/demo.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/diff.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/edu_v27.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/education.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/enterprise/__init__.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/enterprise/billing_stub.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/enterprise/multi_tenant.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/enterprise/quota.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/eta.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/fun/__init__.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/fun/bingo_card.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/gh_check_run.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/gui_payloads.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/gui_v27_extras.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/gui_windows.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/har_replay.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/hardware_keys.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/heatmap.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/history.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/i18n.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/importers/__init__.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/importers/burp_zap.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/incremental/__init__.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/incremental/_legacy.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/incremental/diff_scan.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/incremental/smart_skip.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/integrations/__init__.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/integrations/cisa_kev.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/integrations/epss.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/integrations/github_issues.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/integrations/osint.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/integrations/sucuri_sitecheck.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/integrations/threat_intel.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/integrations/ticketing.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/integrations/tor_proxy.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/integrations/virustotal.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/integrations/webhooks_chat.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/interactsh.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/issue_push.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/js_plugin.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/kev.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/licensing.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/log.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/marketplace.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/marketplace_v27.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/mobile_app_discovery.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/models.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/monitors.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/notify.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/observability.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/password_audit.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/payloads.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/perf/connection_pool.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/perf/parallel_sites.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/perf_v27.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/playbook.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/policy.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/pr_inspector.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/prove.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/py.typed +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/recommend.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/reference_diff.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/region_egress.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/remediation_videos.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/report_query.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/reporters/__init__.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/reporters/attestation.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/reporters/auditor_pdf.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/reporters/badge_svg.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/reporters/board_one_pager.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/reporters/bounty_format.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/reporters/burp_export.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/reporters/comparison_two_sites.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/reporters/compliance_attestation.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/reporters/csv_out.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/reporters/d3fend_mapping.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/reporters/dashboard.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/reporters/diff_agency.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/reporters/diff_viewer.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/reporters/docx_report.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/reporters/eli5_toggle.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/reporters/exec_pdf.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/reporters/executive_pack.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/reporters/executive_tldr.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/reporters/finding_heatmap.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/reporters/gdpr_dsr_report.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/reporters/html.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/reporters/issue_export.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/reporters/live_sync.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/reporters/org_dashboard.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/reporters/pdf_custom_branding.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/reporters/public_page.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/reporters/risk_forecast.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/reporters/share_link.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/reporters/snapshot_compare.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/reporters/translated_summary.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/reporters/trend_over_time.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/reporters/user_template.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/reporters/vex_export.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/reporters/xlsx_out.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/reporters/xlsx_pivot.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/risk.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/risk_weights.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/sbom.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/scan_zip.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/scanner.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/scheduler.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/siem.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/sites.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/sla.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/slack_app.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/spider.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/ssh_audit.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/tags.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/template_engine.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/template_signature.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/threat_intel_v2.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/tray.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/trust_v27.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/turbo_engine.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/ua_rotation.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/ux_extras.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/waf_rules.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/watchers.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan/workflow.py +0 -0
- {wpsecscan-2.7.3 → wpsecscan-2.8.0}/wpsecscan.egg-info/dependency_links.txt +0 -0
- {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.
|
|
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
|
|
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
|
-
|
|
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.
|
|
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
|
-
|
|
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
|
-
#
|
|
86
|
-
#
|
|
87
|
-
|
|
88
|
-
assert "
|
|
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"
|