最稳妥的做法是用白名单机制只放行get、head、post,其余方法一律拦截;优先用if拦截trace/track并返回444;api路径需单独放行options以支持cors预检,同时严格限制host头和请求头。

最稳妥的做法是用白名单机制只放行业务真正需要的方法,比如 GET、HEAD、POST,其余一律拦截。不建议用黑名单逐个禁用 TRACE、DELETE 等——容易遗漏或被绕过。
用 limit_except 做主入口统一控制
这是官方推荐、语义清晰、性能稳定的方式,适合放在 location / 块中作为默认策略:
- 写在根路径 location 内,能覆盖所有未被其他 location 显式接管的请求,避免路径绕过
- 只允许 GET、HEAD、POST,其余方法(包括 OPTIONS、TRACE、DELETE、PUT、PATCH、CONNECT)自动返回 405 Not Allowed
- 若确定不需要 HEAD(如纯 JSON API),可精简为
limit_except GET POST { deny all; }
API 路径必须单独处理 OPTIONS
浏览器跨域请求前会发 OPTIONS 预检,全局禁用会导致前端直接失败:
- 对
/api/类路径显式放行 OPTIONS,并返回标准 CORS 头 - 同时仍要拦截 TRACE、TRACK、PUT、DELETE 等高危方法,不能因为放行 OPTIONS 就放松其它限制
- 示例:在
location /api/中先判断$request_method = OPTIONS并 return 204,再用 if 拦截高危方法
优先拦截 TRACE 和 TRACK 方法
这两个方法存在明确安全风险(如 XST 攻击),应比白名单更早处理,且用 444 彻底断连:
- 在 server 或 location 块顶部添加:
if ($request_method ~ ^(TRACE|TRACK)$) { return 444; } - 444 不返回任何响应体,比 405 更彻底,也防信息泄露
- 确保该规则位置靠前,否则可能被后续 limit_except 或 if 规则跳过
配合 Host 头和请求头校验增强防护
单靠方法限制不够,攻击常组合异常 Host 或畸形头部绕过:
- 拒绝含端口号的 Host(如 example.com:8080):
if ($host ~ ":[0-9]+$") { return 400; } - 限制请求头缓冲区大小,防超长/畸形头部藏匿非法方法:
client_header_buffer_size 1k; large_client_header_buffers 2 2k; - 可选:检查 User-Agent 是否含扫描器特征(如 sqlmap、nuclei),命中即 return 403











