如何确定请求查询字符串的编码

时间:2012-08-14 17:02:48

标签: unicode encoding sql-injection httprequest httpmodule

假设我有一个.NET HttpModule来分析传入的请求,以检查可能的攻击,例如Sql Injection。 现在假设我的应用程序的用户在表单字段中输入以下内容并提交它:

&#039&#032&#079&#082&#032&#049&#061&#049

这是' OR 1=1的Unicode。所以在请求中我得到了类似的东西:

http://example.com/?q=%26%23039%26%23032%26%23079%26%23082%26%23032%26%23049%26%23061%26%23049

我的HttpModule看起来很好(没有Sql注入),但服务器会正​​确解码为q=' OR 1=1,我的过滤器会失败。

所以,我的问题是:Is there any way to know at that point what is the encoding used by the request query string, so I can decode it and detect the attack?

我猜浏览器必须告诉服务器请求的编码方式,因此可以正确解码。或者我错了吗?

2 个答案:

答案 0 :(得分:1)

您看到的是URL编码,其中百分号后跟2个十六进制数字表示单个编码的字节八位字节。在HTML中,以&符号开头并以分号结尾的实体包含实体名称或显式Unicode代码点值。

在浏览器和服务器之间通过网络发送的是http://example.com/?q=%26%23039%26%23032%26%23079%26%23082%26%23032%26%23049%26%23061%26%23049,但在服务器接收到解码后,逻辑上实际上代表http://example.com/?q=&#039&#032&#079&#082&#032&#049&#061&#049。当您的代码读取查询字符串时,它应该接收&#039&#032&#079&#082&#032&#049&#061&#049。服务器不应该进一步解码为' OR 1=1,您必须在自己的代码中执行此操作。

如果您允许URL查询字符串按原样指定SQL查询过滤器,那么您首先要犯的是错误。这表明您正在动态构建SQL查询,而不是使用参数化SQL查询或存储过程,因此您将对SQL注入攻击保持开放态度。你不应该使用它。参数化SQL查询和存储过程不受注入攻击,因此只允许客户端在URL中提交单个参数值。然后,您的服务器代码可以从URL查询中提取单个值,并根据需要将它们传递给SQL参数。 SQL引擎将确保对值进行限制和格式化以避免攻击。你不应该手动处理它。

答案 1 :(得分:1)

  

服务器会将其正确解码为q=' OR 1=1

不应该。没有正当理由(*)在SQL查询中使用它之前,应用程序会对&#039...字符串进行HTML解码。 HTML解码是客户端出现的。

(*这是无效的原因:应用程序作者没有最模糊的想法他们正在做什么,尝试编写输入HTML转义函数 - 首先是一个误导的想法 - 并且由于无能写一个输入 - 转义函数而不是...但这是一个不太可能的情况。希望。)

  

有没有办法知道请求查询字符串

使用的编码是什么

没有。一些Web应用程序防火墙试图通过将他们可以想到的每种解码方案应用于传入数据来解决这个问题,并且如果中的任何匹配可疑的东西,则触发,以防应用程序碰巧有任意这种类型的解码器位于输入和易受攻击的系统之间。

这可能会导致性能下降以及误报率增加,对于尝试所有可能的两个或更多解码器组合的WAF来说,情况更是如此。 (例如,T1IrMQ是基于64位编码,URL编码的OR 1 SQL攻击,还是仅仅是车牌?)

你采取这个想法有多远是在你捕获的潜在攻击数量与你对应用程序真实用户的负面影响之间进行权衡。没有一个'正确'的解决方案,因为最终你永远无法提供针对应用程序之外的层中的应用程序漏洞的完全保护(也就是“WAF不起作用”)。