我的目标是创建一个IIS管理模块,该模块查看请求并过滤掉POST中的内容(XSS攻击,SQL注入等)。
然而,我现在挂断了实际过滤请求的过程。这是我到目前为止所得到的:
在Module的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,实际上它确实正确地替换了文本。
但是,在请求过滤器中,存在2个问题。 我目前在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页面获取从表单传递的值,并忽略我尝试执行的任何过滤。
答案 0 :(得分:0)
这里有一些问题,但是为了将来的参考,接收未过滤帖子的页面以及被评估过滤器两次的过滤器的原因是你可能以某种方式访问请求对象在你设置之前Request.Filter。这可能导致它评估输入流,按原样运行当前设置的过滤器链,并返回该流。
例如,简单地访问Request.Form [“something”]会导致它在那个时间点评估输入流,运行整个过滤器链。在此时间点之后对Request.Filters的任何修改都没有效果,并且似乎忽略了此过滤器。
您可以做的是,但ASP.NET也提供了请求验证来解决其中一些问题(XSS)。但是,通常不会通过字符串连接构建查询,而不是通过输入清理来避免Sql注入,尽管深度防御通常是一个好主意。