【问题标题】:Request.Filter in an IIS Managed ModuleIIS 托管模块中的 Request.Filter
【发布时间】:2012-05-11 06:01:47
【问题描述】:

我的目标是创建一个 IIS 托管模块,它查看请求并从 POST 中过滤掉内容(XSS 攻击、SQL 注入等)。
但是,我现在挂断了实际过滤请求的过程。到目前为止,这是我所得到的:

在模块的初始化中,我将 HttpApplication.BeginRequest 设置为本地事件处理程序。在那个事件处理程序中,我设置了以下几行:

if (application.Context.Request.HttpMethod == "POST")
    {
        application.Context.Request.Filter = new HttpRequestFilter(application.Context.Request.Filter);
    }

我还在application.Context.Response.Filter上设置了一个HttpResponseFilter

HttpRequestFilter 和 HttpResponseFilter 是 Stream 的实现。

在响应过滤器中,我进行了以下设置(Stream.Write 的覆盖):

public override void Write(byte[] buffer, int offset, int count)
    {
        var Content = UTF8Encoding.UTF8.GetString(buffer);
        Content = ResponseFilter.Filter(Content);
        _responseStream.Write(UTF8Encoding.UTF8.GetBytes(Content), offset, UTF8Encoding.UTF8.GetByteCount(Content));
    }

ResponseFilter.Filter 是一个简单的 String.Replace,事实上,它可以正确地替换文本。

然而,在请求过滤器中,有两个问题。 我目前在 RequestFilter 中的代码(Stream.Read 的覆盖):

public override int Read(byte[] buffer, int offset, int count)
{
    var Content = UTF8Encoding.UTF8.GetString(buffer);
    Content = RequestFilter.Filter(Content);
    if (buffer[0]!= 0)
    {
        return _requestStream.Read(UTF8Encoding.UTF8.GetBytes(Content), offset, UTF8Encoding.UTF8.GetByteCount(Content));
    }
    return _requestStream.Read(buffer, offset, count);
}

这有两个问题。首先,过滤器被调用两次,而不是一次,其中一个请求基本上是 /0 的流。 (缓冲区 [0] 上的 if 检查目前过滤了这个,但我认为我设置错误)

其次,即使我在读取中正确地使用 .GetString 抓取内容,然后在 RequestFilter.Filter(一个美化的 string.replace()) 中更改它,当我在 if 语句中返回字节编码的内容时,输入未修改。

这是我想要弄清楚的:

1) 有什么我可以在过滤器之前检查以确保我检查的只是 POST 而不是其他时间被调用的?我没有正确设置 Application.Context.Request.Filter 吗?

2) 我真的很困惑为什么没有显示将内容重写到 _requestStream(我发送给班级的 HttpApplication.Context.Request.Filter)。任何关于我做错的事情的意见将不胜感激。

另外,HttpApplication.Request 和 HttpApplication.Context.Request 之间有什么区别吗?

编辑:有关更多信息,我正在一个简单的 .aspx 页面上进行测试,该页面具有一个文本框、一个按钮和一个标签,并且在按钮单击时将文本框文本分配给标签的文本。理想情况下,如果我将内容放在应该过滤的文本框中,我的理解是通过拦截和重写帖子,我可以使内容按修改后的方式访问服务器。我已经在模块和代码中使用断点运行了测试,并且模块在 .aspx 页面上的代码被命中之前完成。 .aspx 页面获取从表单传递的值,并忽略我尝试执行的任何过滤。

【问题讨论】:

  • 这完全是执行此类过滤的错误位置(毫无疑问,这就是现有此类模块不容易获得的原因)。特别是,XSS 攻击源于您返回给用户的数据被泄露; SQL 注入源于您发送到数据库的数据被泄露。在上述任何操作发生之前很久就操纵用户发送到您的网络服务器的数据是有缺陷的,并且可能导致各种错误。例如,假设“Mr O'Reilly”将他的名字提交给脚本:那么该脚本将处理不正确的姓氏......
  • 当您查看 POST 时,您可以查看正在发送的内容的具体值。通过查看这些值并识别攻击模式(XSS、SQL 等),您可以过滤掉这些内容。我可以进入每个页面并清理每个不正确的输入,但是我需要更新数百个地方,我希望我可以在托管模块中编写一些通用规则来加快速度。就这样。我真的认为这是不可能的。
  • 这个链接有帮助吗? stackoverflow.com/questions/3240170/…

标签: iis filtering httpmodule


【解决方案1】:

这里发生了一些问题,但为了将来参考,解释接收未过滤帖子的页面以及被评估两次的过滤器的原因是您可能在设置之前以某种方式访问​​请求对象请求过滤器。这可能会导致它评估输入流,按原样运行当前设置的过滤器链,并返回该流。

例如,简单地访问 Request.Form["something"] 会导致它评估输入流,在那个时间点运行整个过滤器链。在此时间点之后对 Request.Filters 的任何修改都将无效,并且会显示此过滤器被忽略。

您想做的事情是可能的,而且 ASP.NET 还提供了请求验证来解决其中一些问题 (XSS)。但是,通常通过从不通过字符串连接构造查询来避免 Sql 注入,而不是通过输入清理,尽管深度防御通常是一个好主意。

【讨论】:

    猜你喜欢
    • 2016-01-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-02-23
    • 1970-01-01
    • 2023-03-21
    相关资源
    最近更新 更多