HTTP请求方法限制只允许GET和POST,本质上就是在Web服务器层面做一道"安检门"——把PUT、DELETE、OPTIONS、PATCH、TRACE等非核心方法全部拦截掉,只放行最常用的两种。这样做的核心目的是缩小攻击面,防止攻击者利用非常规HTTP方法绕过安全策略、执行未授权操作或者触发服务器漏洞。具体怎么做?在Nginx里加一段if判断拒绝非GET/POST请求,在Apache里用Rewrite规则拦截,在IIS里通过请求筛选模块配置,在代码层面也可以用中间件统一过滤。下面我把每种方案的原理、配置细节、注意事项全部讲透。
为什么要限制HTTP请求方法?先搞清楚风险在哪
HTTP协议定义了多种请求方法,GET用于获取资源,POST用于提交数据,这两个是Web应用最基础的交互方式。但除此之外还有PUT(上传/替换资源)、DELETE(删除资源)、PATCH(部分更新)、OPTIONS(查询支持的方法)、TRACE(回显请求)等等。这些方法本身不是"坏"的,RESTful API设计中会大量使用PUT和DELETE。但问题在于,很多传统网站、CMS系统、后台管理系统根本不需要这些方法,开放它们就等于多开了几扇没人看守的窗户。
攻击者利用非常规方法能干什么?举几个真实场景:用PUT方法直接上传一个WebShell文件到服务器目录;用DELETE方法删除关键配置文件或用户数据;用TRACE方法发起跨站追踪攻击(XST);用OPTIONS方法探测服务器支持哪些接口和方法,为后续攻击做侦察。2010年Apache的"Range头攻击"就是利用了非常规请求的处理缺陷。所以,限制方法是一种"默认拒绝"的安全策略,属于纵深防御体系里非常实用的一环。
Nginx中限制HTTP请求方法的完整配置
Nginx是目前使用量最大的Web服务器和反向代理,它提供了$request_method变量可以直接判断当前请求使用的方法。最简单的做法是在server块或者location块里加if判断:
if ($request_method !~ ^(GET|POST)$ ) {
return 405;
}
这段代码的意思是:如果请求方法不是GET也不是POST,直接返回405 Method Not Allowed状态码。405是HTTP标准状态码,比直接返回403更语义化,告诉客户端"这个方法不被允许"。如果你想更彻底,可以针对特定路径做限制,比如只对上传接口、API接口做方法过滤,而不是全局拦截:
location /api/ {
if ($request_method !~ ^(GET|POST)$ ) {
return 405;
}
proxy_pass http://backend;
}
需要注意一个坑:Nginx的if指令在某些场景下有"if is evil"的说法,但在这里只是简单的返回操作,不涉及复杂逻辑,实际使用是安全的。另外,如果你的网站需要支持WebDAV或者某些特殊功能用到了PUT/DELETE,那就不能全局限制,要按路径精细化配置。
Apache中通过Rewrite规则实现方法限制
Apache的配置逻辑和Nginx不同,它主要通过mod_rewrite模块来实现。在.htaccess文件或者虚拟主机配置里可以这样写:
RewriteEngine On
RewriteCond %{REQUEST_METHOD} !^(GET|POST)$ [NC]
RewriteRule .* - [R=405,L]
这段规则的逻辑是:当请求方法不匹配GET或POST时,重写到当前URL并返回405状态码。[NC]表示不区分大小写,[L]表示这是最后一条规则。如果你用的是Apache 2.4以上版本,还可以用更现代的方式,在Directory或Location段里用Require指令配合表达式:
<RequireAll>
Require method GET POST
</RequireAll>
这种写法更清晰,而且Apache会自动处理不允许的方法并返回405。对于WordPress、Drupal这类CMS系统,通常在根目录的.htaccess里加一条Rewrite规则就够了,不会影响后台正常的文件上传(因为上传走的是POST)。
IIS服务器上的请求筛选配置方法
Windows Server上跑IIS的站长,可以通过"请求筛选"(Request Filtering)功能来限制方法。操作路径是:打开IIS管理器 → 选择网站 → 双击"请求筛选" → 切换到"HTTP谓词"选项卡 → 在"允许的谓词"里只保留GET和POST,把其他的删掉。这样IIS会自动拒绝任何非GET/POST的请求并返回405.3错误。
如果你想用web.config文件来管理(方便版本控制和部署),可以这样配置:
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.webServer>
<security>
<requestFiltering>
<verbs applyToWebDAV="false">
<add verb="GET" allowed="true" />
<add verb="POST" allowed="true" />
<add verb="HEAD" allowed="false" />
<add verb="PUT" allowed="false" />
<add verb="DELETE" allowed="false" />
</verbs>
</requestFiltering>
</security>
</system.webServer>
</configuration>
注意这里HEAD方法默认也被禁了。HEAD和GET几乎一样只是不返回响应体,很多场景下是需要的(比如CDN缓存验证、链接检查)。如果你的业务需要HEAD,就把allowed改成true。这个配置文件可以直接放在网站根目录,IIS会自动加载。
应用层代码实现:中间件过滤请求方法
除了在Web服务器层面拦截,在应用代码层面做一层过滤是更灵活的方案。以Node.js的Express框架为例,可以写一个全局中间件:
app.use((req, res, next) => {
const allowedMethods = ['GET', 'POST'];
if (!allowedMethods.includes(req.method)) {
return res.status(405).json({
error: 'Method Not Allowed',
message: 'Only GET and POST methods are permitted'
});
}
next();
});
Python的Flask框架可以用装饰器或者before_request钩子:
@app.before_request
def limit_methods():
if request.method not in ['GET', 'POST']:
return 'Method Not Allowed', 405
Java的Spring Boot可以通过Filter或者HandlerInterceptor实现:
@Component
public class MethodFilter implements Filter {
@Override
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
HttpServletRequest httpRequest = (HttpServletRequest) request;
String method = httpRequest.getMethod();
if (!"GET".equals(method) && !"POST".equals(method)) {
HttpServletResponse httpResponse = (HttpServletResponse) response;
httpResponse.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED);
return;
}
chain.doFilter(request, response);
}
}
应用层过滤的好处是可以做更细粒度的控制,比如对某些接口允许PUT,对某些只允许GET。但缺点是请求已经到达应用了,如果前面没有Web服务器层面的拦截,恶意请求仍然会消耗应用资源。所以最佳实践是"服务器层+应用层"双重过滤。
限制方法之后需要注意的几个关键问题
第一,不要一刀切。如果你的网站有RESTful API、文件管理功能、WebDAV支持,这些场景天然需要PUT、DELETE等方法。全局限制会导致这些功能直接瘫痪。正确做法是按路径或按模块分别配置,只对不需要非常规方法的区域做限制。
第二,405状态码要正确返回。有些人图省事直接返回403 Forbidden,这在语义上是错误的。403表示"你没有权限",405表示"这个方法不被允许"。对于安全审计和日志分析来说,正确的状态码能帮助你快速定位问题。同时建议在返回405时附带Allow响应头,告诉客户端哪些方法是被允许的:
add_header Allow "GET, POST" always;
第三,测试要充分。配置完之后用curl命令验证一下:
curl -X PUT http://yourdomain.com/test curl -X DELETE http://yourdomain.com/test curl -X OPTIONS http://yourdomain.com/test
如果返回405就说明配置生效了。同时也要确认正常的GET和POST请求不受影响。
第四,这只是安全策略的一层,不能替代其他防护。限制HTTP方法防的是"利用非常规方法攻击"这一类威胁,但SQL注入、XSS、CSRF、文件上传漏洞这些问题,光靠限制方法是解决不了的。它应该和WAF(Web应用防火墙)、输入验证、权限控制、HTTPS加密等措施配合使用,形成完整的安全体系。
从合规和安全标准角度看方法限制的意义
在等保2.0、ISO 27001、PCI DSS等安全合规框架中,都有"最小权限原则"和"减少攻击面"的要求。限制不必要的HTTP请求方法就是这两个原则的具体落地。很多安全扫描工具(如Nessus、OpenVAS)在做Web安全检测时,会专门检查服务器是否开放了不必要的HTTP方法,如果发现PUT、DELETE、TRACE等方法可用且没有合理用途,会标记为中高风险项。所以做好这一步,不仅是主动防御,也是过安全审计的基本要求。
还有一个容易被忽视的点:TRACE方法。虽然现代浏览器已经很少主动发送TRACE请求,但如果服务器支持TRACE,攻击者可以利用它发起XST(Cross-Site Tracing)攻击,窃取用户的Cookie信息。所以在限制方法的时候,TRACE一定要关掉。在Apache里可以用TraceEnable Off,在Nginx里没有内置TRACE支持(默认就不响应),IIS里需要在请求筛选中明确禁用。
总结:怎么做才是最优解
网站安全之HTTP请求方法限制,核心思路就是"默认拒绝、按需放行"。具体操作上,先梳理你的网站哪些功能需要哪些HTTP方法,然后在Web服务器层面做全局或局部限制,再在应用层加一道保险。配置不复杂,十分钟就能搞定,但效果实实在在——它砍掉了一整类攻击路径,让攻击者少了很多可利用的入口。不要觉得这是小题大做,安全这件事从来都是细节决定成败。把每一个不起眼的小口子堵上,整体安全性就会上一个台阶。
