Nginx中禁用危险HTTP方法主要通过limit_except指令(推荐)或if+return方式实现,仅允许GET、HEAD、POST,其余返回405;需特别防范TRACE和OPTIONS风险,并用curl验证生效。

<p>在 Nginx 中禁用危险 HTTP 方法(如 <strong>PUT</strong>、<strong>DELETE</strong>、<strong>TRACE</strong>、<strong>OPTIONS</strong>、<strong>CONNECT</strong> 等)主要是通过 <strong>limit_except</strong> 指令或 <strong>if + return</strong> 方式实现,核心是只允许安全方法(<strong>GET</strong>、<strong>HEAD</strong>、<strong>POST</strong>),其余一律拒绝。</p>
<H3>使用 limit_except 限制非安全方法(推荐)</H3>
<p>这是最规范、语义清晰的方式,适用于 location 块内,仅放行指定方法,其他自动返回 405(Method Not Allowed):</p>
<pre><code>location / {
limit_except GET HEAD POST {
deny all;
}
# 其他配置,如 root、index 等
}</code></pre>
<p>说明:<br>
• <strong>GET</strong> 和 <strong>HEAD</strong> 安全且常用于静态资源访问;<br>
• <strong>POST</strong> 通常用于表单提交,需根据业务判断是否保留;<br>
• 若后端 API 明确不需要 POST(比如纯静态站),可只保留 GET HEAD;<br>
• <strong>limit_except</strong> 不影响内部重定向(如 error_page),也不影响 proxy_pass 的上游方法控制。</p>
<H3>用 if 判断 $request_method 拦截(备选方案)</H3>
<p>当需要更灵活控制(例如记录日志、返回自定义状态码)时可用此方式,但注意 <strong>if 在 location 中有局限性,不建议嵌套复杂逻辑</strong>:</p>
<pre><code>location / {
if ($request_method !~ ^(GET|HEAD|POST)$) {
return 405;
}
# 后续正常配置
}</code></pre>
<p>注意:<br>
• <strong>$request_method</strong> 是 Nginx 内置变量,区分大小写(如 PUT ≠ put);<br>
• 避免在 if 中调用 proxy_pass 或 rewrite,可能导致行为异常;<br>
• 返回 405 是标准做法,比 403 更准确(表示方法不被支持,而非权限拒绝)。</p>
<H3>特别处理 TRACE 和 OPTIONS(防御潜在风险)</H3>
<p>TRACE 方法易被用于跨站追踪(XST),OPTIONS 可能泄露服务器信息。即使已用上述方式,也建议显式关闭:</p>
<ul>
<li>确保未启用 <strong>add_header Access-Control-Allow-Methods</strong> 泄露敏感方法</li>
<li>若无需 CORS,不要配置 <strong>add_header Access-Control-Allow-Origin</strong></li>
<li>对健康检查路径(如 /health)可单独放开 OPTIONS,避免干扰监控</li>
</ul>
<H3>验证是否生效</H3>
<p>部署后用 curl 测试关键方法:</p>
<pre><code>curl -X PUT https://yoursite.com/test.txt -I
curl -X TRACE https://yoursite.com/ -I
# 应返回 405 或 403,响应头中不应含 Allow: PUT,DELETE 等</code></pre>
<p>同时检查 Nginx 错误日志:<br>
• 若出现 <strong>"method not allowed"</strong> 提示,说明 limit_except 生效;<br>
• 若返回 404 而非 405,可能是 location 匹配不到,需检查路径和正则优先级。</p>