{"record":{"id":"0f2a4f728f2dc49a","repo":"wpscanteam/wpscan","slug":"the-target-is-responding-with-a-403-this-might-be","errorCode":null,"errorMessage":"The target is responding with a 403, this might be due to a WAF. Well... --random-user-agent didn't work, use --force to skip this check if needed.","messagePattern":"The target is responding with a 403, this might be due to a WAF\\. Well\\.\\.\\. --random-user-agent didn't work, use --force to skip this check if needed\\.","errorType":"exception","errorClass":"WPScan::Error::AccessForbidden","httpStatus":403,"severity":"error","filePath":"app/controllers/core.rb","lineNumber":77,"sourceCode":"        output('help', help: option_parser.full_help, simple: false) if WPScan::ParsedCli.hh\n        output('version') if WPScan::ParsedCli.version\n\n        exit(WPScan::ExitCode::OK) if WPScan::ParsedCli.help || WPScan::ParsedCli.hh || WPScan::ParsedCli.version\n      end\n\n      # Checks that the target is accessible, raises related errors otherwise.\n      #\n      # @return [ Void ]\n      def check_target_availability\n        res = WPScan::Browser.get(target.url)\n\n        case res.code\n        when 0\n          raise Error::TargetDown, res\n        when 401\n          raise Error::HTTPAuthRequired\n        when 403\n          raise Error::AccessForbidden, WPScan::ParsedCli.random_user_agent unless WPScan::ParsedCli.force\n        when 407\n          raise Error::ProxyAuthRequired\n        end\n\n        handle_redirection(res)\n      end\n\n      # Checks whether the response or its redirect chain contains a SAMLRequest,\n      # indicating that the target requires SAML authentication.\n      #\n      # @param [ Addressable::URI ] effective_uri  Final URL after following redirects\n      # @param [ Typhoeus::Response ] homepage_res Response whose redirect chain to inspect\n      #\n      # @return [ Boolean ]\n      def saml_request?(effective_uri, homepage_res = nil)\n        return false unless effective_uri\n\n        return true if effective_uri.to_s.match?(/[?&]SAMLRequest/i)","sourceCodeStart":59,"sourceCodeEnd":95,"githubUrl":"https://github.com/wpscanteam/wpscan/blob/62c9cef471de90095f6b42245a11d0f8172d19c9/app/controllers/core.rb#L59-L95","documentation":"Raised by Core#check_target_availability (app/controllers/core.rb:77) when the target answers the initial GET with HTTP 403 and --force is not set. This variant is constructed with WPScan::ParsedCli.random_user_agent == true, i.e. the scan already ran with --random-user-agent and still received 403, so the message states the random UA did not help and points at --force. It almost always indicates a WAF or server-level rule (Cloudflare, ModSecurity, IP allowlist) blocking the scanner for reasons beyond the User-Agent.","triggerScenarios":"`wpscan --url http://target --random-user-agent` (or random_user_agent: true in config) where WPScan::Browser.get(target.url) returns code 403: WAF rule matching scanner TLS/HTTP fingerprint, IP-based deny or allowlist, country block, or a global access rule — and no --force on the command line.","commonSituations":"Cloudflare/Sucuri in front of the site; ModSecurity CRS rules; nginx/apache allow-deny rules blocking the scanner IP; hosting provider blocking datacenter IP ranges; scanning through a VPN whose egress IP is blacklisted.","solutions":["Re-run with --force to skip the 403 check if you accept scanning a site that is blocking you","Get your scanning IP allowlisted by the site owner, or scan from an allowed network","Route the scan through a different egress IP via --proxy that is not blocked","If you administer the site, temporarily relax the WAF/IP rule for your IP during the scan"],"exampleFix":"# before\nwpscan --url http://target --random-user-agent\n# => ...403 ... --random-user-agent didn't work, use --force to skip this check if needed.\n\n# after\nwpscan --url http://target --force","handlingStrategy":"fallback","validationCode":"# Detect the 403 block before running the scan\nres = WPScan::Browser.get('http://target')\nraise 'blocked (403): use --force or an allowed IP' if res.code == 403","typeGuard":null,"tryCatchPattern":"begin\n  scan.run\nrescue WPScan::Error::AccessForbidden => e\n  retry_with(force: true) if e.random_user_agent_used # conscious fallback: skip the 403 check\nend","preventionTips":["Pre-probe the target with curl to detect 403 before committing to a long scan","Ask the site owner to allowlist the scanning IP","Keep --force as an explicit, deliberate fallback only","Inspect WAF headers (cf-ray, x-sucuri) in the 403 response to identify the blocker"],"tags":["http-403","waf","blocking","user-agent","firewall"],"backgroundTag":"http-403-forbidden","analyzedSha":"62c9cef471de90095f6b42245a11d0f8172d19c9","analyzedAt":"2026-08-21T17:10:47.902Z","schemaVersion":2},"datasetVersion":"2026-08-21T18:17:14.833Z"}