游客发表
上周帮朋友排查一个渗透测试报告,扫描器给他们的服s方法Nginx服务器标了个中危——"OPTIONS方法启用"。朋友一脸懵:我根本没写过任何跟OPTIONS有关的禁用配置,这玩意儿哪来的服s方法?
这就是问题所在。很多人以为不主动开启就不会存在,禁用但现实是服s方法,绝大多数Web服务器默认就会响应OPTIONS请求。禁用你什么都不做,服s方法它就在那里。禁用
OPTIONS是服s方法HTTP/1.1协议里定义的方法之一。它的禁用本意不坏——让客户端询问服务器某个资源支持哪些方法。比如你发一个OPTIONS /api/users,服s方法服务器会返回Allow: GET,禁用 POST, PUT, DELETE, OPTIONS。听起来挺合理,服s方法对吧?禁用
但安全视角下,这东西就是个信息泄露的口子。攻击者不需要认证,不需要任何凭证,一个简单的请求就能拿到你API支持的完整方法列表。哪些接口允许PUT?哪些允许DELETE?全暴露了。我见过一个案例,某内部系统通过OPTIONS响应暴露了TRACE方法还开着,直接给XST攻击铺了路。
更麻烦的是,OPTIONS请求通常不会出现在业务日志的告警规则里。它太"正常"了,正常到很多WAF默认都不拦。攻击者可以拿它当探针,安安静静地摸清你的接口结构。
Apache默认在httpd.conf里通过<Limit>或<LimitExcept>控制方法。很多发行版的默认配置里,OPTIONS是放行的。你可以用<LimitExcept GET POST>把其他方法全掐掉,但要注意别把HEAD也误伤了——有些健康检查依赖它。
Nginx的处理方式不太一样。它没有直接的"禁用方法"指令,得靠if判断或者limit_except块。我一般推荐后者,写在location里:
location /api/ { limit_except GET POST { deny all; } } 这样除了GET和POST,其他方法一律403。干净利落。但有个坑:limit_except在if块里不生效,别问我怎么知道的,踩过。
IIS稍微省心点,web.config里加一段<requestFiltering>,把verbs配一下就行。不过IIS的默认站点模板有时候会带上WebDAV,那玩意儿会强制开启OPTIONS,得先把WebDAV模块卸了。
会。CORS预检请求用的就是OPTIONS。如果你有跨域需求,浏览器会先发一个OPTIONS问服务器"我能不能发这个跨域请求",你把OPTIONS禁了,跨域直接挂掉。
所以正确的做法不是一刀切,而是区分场景。纯后端API、没有跨域调用的,直接禁。有跨域的,只对特定路径放行OPTIONS,并且限制来源。我通常会在Nginx里这么写:
location /api/ { if ($request_method = OPTIONS) { add_header Access-Control-Allow-Origin "https://trusted.example.com"; add_header Access-Control-Allow-Methods "GET, POST"; add_header Access-Control-Allow-Headers "Content-Type, Authorization"; add_header Content-Length 0; return 204; } limit_except GET POST { deny all; } } 注意那个return 204,别用200,204才是预检请求该有的响应码。还有Content-Length 0,有些老版本浏览器对空body的204处理有bug,加上这个稳妥点。
另外TRACE方法也顺手禁了吧。它比OPTIONS更危险,能回显请求内容,配合XSS可以偷Cookie。Apache里TraceEnable off一行搞定,Nginx默认就不支持TRACE,不用管。
改完配置别急着上线。用curl测一下:
curl -X OPTIONS -i https://your-site.com/api/users
看返回是不是403或者405。如果还是200并且带着Allow头,说明配置没生效——检查一下是不是被其他location块覆盖了,或者LB层给拦了。
还有个偏门情况:某些PHP框架的路由会自动处理OPTIONS请求,返回一个空的200。这种得在框架层面禁,改Nginx没用。Laravel里可以在路由上加->where('_method', '^(?!OPTIONS).*$'),不过更推荐直接用中间件拦。
说到底,禁用OPTIONS不是什么高深的安全措施,但它属于那种"做了没坏处、不做可能出事"的基线配置。花五分钟改一下,比事后写渗透测试整改报告轻松多了。
```友情链接