我的目标是创建一个 IIS 托管模块,它查看请求并从 POST 中过滤掉内容(XSS 攻击、SQL 注入等)。
但是,我现在挂断了实际过滤请求的过程。这是我到目前为止所得到的:
在模块的 Init 中,我将 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] 目前过滤了这个,但我认为我设置错了)
其次,即使我在读取中正确地使用 .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 页面获取从表单传递的值,并忽略我尝试执行的任何过滤。