You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在ASP.NET WebForms中禁用HTTP方法隧道及实现疑问

问题背景

在MicroFocus Web安全扫描中检测到高危漏洞**"Often Misused: HTTP Method Override"**,该漏洞核心风险为:攻击者可通过GET、POST等可信HTTP方法,附加X-HTTP-Method、XHTTP-Method-Override、X-Method-Override请求头或_method查询参数,传递PUT、DELETE等受限方法,让应用按请求头中的方法解析请求,进而绕过权限控制或执行未授权操作。

已有开发者针对Fortify WebInspect的同类问题,实现了Java Servlet过滤器,检测到可疑请求头/参数时返回405状态码,代码如下:

@Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {

    HttpServletRequest hsReq = (HttpServletRequest) req;
    HttpServletResponse hsRes = (HttpServletResponse) res;

    hsRes.setHeader("Cache-Control", "no-cache, no-store, must-revalidate");
    hsRes.setHeader("Pragma", "no-cache");
    hsRes.setDateHeader("Expires", 0);
    hsRes.setHeader("X-XSS-Protection", "1; mode=block");
    hsRes.addHeader("X-Content-Type-Options", "nosniff");
    hsRes.setHeader("Content-Security-Policy", "frame-ancestors 'none'; default-src *; style-src 'self' http://* 'unsafe-inline'; script-src 'self' http://* 'unsafe-inline' 'unsafe-eval'");
    hsRes.setHeader("X-FRAME-OPTIONS", "DENY");
    hsRes.setHeader("Strict-Transport-Security", "max-age=31536000; includeSubDomains;");

    // 修复"Often Misused: HTTP Method Override"漏洞
    hsRes.setHeader("Access-Control-Allow-Methods", "GET, POST");
    String methodParam = hsReq.getParameter("_method");
    if (methodParam != null){
        LOG.error("\n Bad actor is attempting to use HTTP Method Tunneling. \n");
        hsRes.reset();
        hsRes.setStatus(HttpServletResponse.SC_METHOD_NOT_ALLOWED);
        return;
    }
    String xhmHeader = hsReq.getHeader("x-http-method");
    String xhmoHeader = hsReq.getHeader("x-http-method-override");
    String xmoHeader = hsReq.getHeader("x-method-override");
    if ((xhmHeader != null) || (xhmoHeader != null) || (xmoHeader != null)){
        LOG.error("\n Bad actor is attempting to use HTTP Method Tunneling. \n");
        hsRes.reset();
        hsRes.setStatus(HttpServletResponse.SC_METHOD_NOT_ALLOWED);
        return;
    }

    chain.doFilter(req, res);
}
ASP.NET WebForms中的实现方案

1. 自定义HttpModule的放置与调用

ASP.NET WebForms无直接对应Servlet Filter的组件,可通过HttpModule实现全局请求拦截,步骤如下:

步骤1:创建HttpModule类

在项目中新建类(如HttpMethodOverrideModule.cs),实现IHttpModule接口,移植核心逻辑:

using System;
using System.Web;
using System.Diagnostics;

namespace YourNamespace
{
    public class HttpMethodOverrideModule : IHttpModule
    {
        public void Init(HttpApplication context)
        {
            context.BeginRequest += OnBeginRequest;
        }

        private void OnBeginRequest(object sender, EventArgs e)
        {
            HttpApplication app = (HttpApplication)sender;
            HttpRequest request = app.Context.Request;
            HttpResponse response = app.Context.Response;

            // 设置安全响应头(与Java代码对应,可按需调整)
            response.Headers["Cache-Control"] = "no-cache, no-store, must-revalidate";
            response.Headers["Pragma"] = "no-cache";
            response.Expires = 0;
            response.Headers["X-XSS-Protection"] = "1; mode=block";
            response.Headers["X-Content-Type-Options"] = "nosniff";
            response.Headers["Content-Security-Policy"] = "frame-ancestors 'none'; default-src *; style-src 'self' http://* 'unsafe-inline'; script-src 'self' http://* 'unsafe-inline' 'unsafe-eval'";
            response.Headers["X-FRAME-OPTIONS"] = "DENY";
            response.Headers["Strict-Transport-Security"] = "max-age=31536000; includeSubDomains;";
            response.Headers["Access-Control-Allow-Methods"] = "GET, POST";

            // 检测_method参数
            string methodParam = request.QueryString["_method"];
            if (!string.IsNullOrEmpty(methodParam))
            {
                EventLog.WriteEntry("Application", "HTTP Method Tunneling attempt via _method parameter.", EventLogEntryType.Error);
                response.Clear();
                response.StatusCode = 405;
                response.End();
                return;
            }

            // 检测可疑请求头
            string xhmHeader = request.Headers["x-http-method"];
            string xhmoHeader = request.Headers["x-http-method-override"];
            string xmoHeader = request.Headers["x-method-override"];
            if (!string.IsNullOrEmpty(xhmHeader) || !string.IsNullOrEmpty(xhmoHeader) || !string.IsNullOrEmpty(xmoHeader))
            {
                EventLog.WriteEntry("Application", "HTTP Method Tunneling attempt via request headers.", EventLogEntryType.Error);
                response.Clear();
                response.StatusCode = 405;
                response.End();
                return;
            }
        }

        public void Dispose()
        {
            // 按需清理资源
        }
    }
}

步骤2:注册HttpModule

在Web.config中根据.NET运行模式配置:

集成模式(.NET Framework 4.0+):

<system.webServer>
  <modules>
    <add name="HttpMethodOverrideModule" type="YourNamespace.HttpMethodOverrideModule" />
  </modules>
</system.webServer>

经典模式:

<system.web>
  <httpModules>
    <add name="HttpMethodOverrideModule" type="YourNamespace.HttpMethodOverrideModule" />
  </httpModules>
</system.web>

2. 更简洁的解决方案:Global.asax直接处理

无需创建独立模块,直接在Global.asax的Application_BeginRequest事件中编写逻辑:

protected void Application_BeginRequest(object sender, EventArgs e)
{
    HttpRequest request = Context.Request;
    HttpResponse response = Context.Response;

    // 检测_method参数与可疑请求头
    bool hasMethodOverride = !string.IsNullOrEmpty(request.QueryString["_method"]) ||
                             !string.IsNullOrEmpty(request.Headers["x-http-method"]) ||
                             !string.IsNullOrEmpty(request.Headers["x-http-method-override"]) ||
                             !string.IsNullOrEmpty(request.Headers["x-method-override"]);

    if (hasMethodOverride)
    {
        EventLog.WriteEntry("Application", "HTTP Method Override attempt detected.", EventLogEntryType.Error);
        response.Clear();
        response.StatusCode = 405;
        response.End();
        return;
    }

    // 可选:设置允许的HTTP方法头
    response.Headers["Access-Control-Allow-Methods"] = "GET, POST";
}

优势:

  • 无需额外类与配置,代码轻量化
  • 全局入口直接处理,逻辑直观易维护

内容的提问来源于stack exchange,提问作者Jim Beaumont

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 06:25:16