{"record":{"id":"b4d7aa042a7fd32e","repo":"dromara/Sa-Token","slug":"host-host","errorCode":null,"errorMessage":"非法请求 host：{host}","messagePattern":"非法请求 host：(.+?)","errorType":"exception","errorClass":"FirewallCheckException","httpStatus":null,"severity":"error","filePath":"sa-token-core/src/main/java/cn/dev33/satoken/strategy/hooks/SaFirewallCheckHookForHost.java","lineNumber":73,"sourceCode":"    public void resetConfig(boolean isCheckHost, String... allowHosts) {\n        this.isCheckHost = isCheckHost;\n        this.allowHosts.clear();\n        this.allowHosts.addAll(Arrays.asList(allowHosts));\n    }\n\n    /**\n     * 执行的方法\n     *\n     * @param req 请求对象\n     * @param res 响应对象\n     * @param extArg 预留扩展参数\n     */\n    @Override\n    public void execute(SaRequest req, SaResponse res, Object extArg) {\n        if(isCheckHost) {\n            String host = req.getHost();\n            if( ! SaStrategy.instance.hasElement.apply(allowHosts, host) ) {\n                throw new FirewallCheckException(\"非法请求 host：\" + host);\n            }\n        }\n    }\n\n}\n","sourceCodeStart":55,"sourceCodeEnd":79,"githubUrl":"https://github.com/dromara/Sa-Token/blob/ac2c7f6e94a78573cf0bcb932dd8b04e68fad189/sa-token-core/src/main/java/cn/dev33/satoken/strategy/hooks/SaFirewallCheckHookForHost.java#L55-L79","documentation":"When sa-token.firewall.check-host is enabled, the Host firewall hook reads the request's Host (req.getHost()) and requires it to be matched by one of the configured allowHosts patterns via SaStrategy.hasElement. A mismatch throws FirewallCheckException with the actual host value in the message. This defends against Host-header poisoning attacks.","triggerScenarios":"Enabling firewall.host-check=true but accessing the app via an IP address, a container hostname, an internal domain, or a port-suffixed Host that is not in allow-hosts; also forged Host headers from attackers.","commonSituations":"Deploying behind a new domain/CDN without updating allow-hosts; Docker/K8s health checks hitting the pod IP so Host is '10.x.x.x'; local testing with localhost while only the production domain is whitelisted; proxy not rewriting the Host header.","solutions":["Add the actual Host value (shown in the error message) to sa-token.firewall.allow-hosts","Or disable the check: sa-token.firewall.host-check=false when you cannot control incoming Hosts","Configure nginx proxy_set_header Host $host; so the upstream sees the intended public host"],"exampleFix":"# before\nsa-token:\n  firewall:\n    host-check: true\n    allow-hosts: [example.com]\n# request with Host: api.example.com -> blocked\n\n# after\nsa-token:\n  firewall:\n    host-check: true\n    allow-hosts: [example.com, api.example.com]","handlingStrategy":"validation","validationCode":"boolean check = SaManager.getConfig().getFirewall().getIsCheckHost();\nif (check) {\n    String host = req.getHost();\n    boolean ok = SaStrategy.instance.hasElement.apply(\n        SaManager.getConfig().getFirewall().getAllowHosts(), host);\n    if (!ok) { /* reject with 400 before firewall hook */ }\n}","typeGuard":null,"tryCatchPattern":"try {\n    chain.doFilter(req, res);\n} catch (FirewallCheckException e) {\n    res.setStatus(400); // Host not allowed\n}","preventionTips":["Keep allow-hosts in sync with every domain/CDN/subdomain that fronts the app","Set proxy_set_header Host correctly on nginx/envoy","Include localhost and the pod IP if K8s probes pass through the check"],"tags":["sa-token","firewall","security","host-header"],"backgroundTag":null,"analyzedSha":"ac2c7f6e94a78573cf0bcb932dd8b04e68fad189","analyzedAt":"2026-08-14T14:36:10.271Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}