我的一个REST API有一个名为“partners”的查询参数,它是一个整数列表,因此您可以在URL中指定多个值。作为XSS攻击的预防措施,我正在使用ESAPI删除输入中的恶意内容。这是问题所在:
我注意到ESAPI编码器cannonicalize方法(使用默认编解码器:HTMLEntityCodec,PercentCodec,JavaScriptCodec)改变了查询参数值,因为它认为& p或& pa是某种编码。见下面的例子
像
这样的东西http://localhost:8080/product?partner=1
按预期工作。
另一方面像
http://localhost:8080/product/?pidentity=1&pidentity=2
规范化后的输入变为
`pidentity=1πdentity=2`
该框架解析时遇到问题,因为它认为这只是一个带有2个分割器的查询参数。
如果请求网址是
http://localhost:8080/product?partner=1&partner=2
规范化后的输入变为
partner=1∂rtner=2
并且& pa变为'∂'。
正如您可能猜到的那样,我尝试更改查询参数的名称,并且工作正常(可能是因为没有任何相应的编码)。有没有人见过,或者可以指导我必须造成这种行为?这可能听起来像我的经验不足,但为了确保防止XSS攻击,我不确定是否应该尝试从默认编码器中删除任何编解码器。
答案 0 :(得分:3)
您目前使用的方法是我们目前称为“Big Hammer”的方法,您尝试对整个URL进行编码,而不是编码由不受信任的来源提供的不受信任或受污染的数据(即,用户)
最好的方法是单独编码每个参数的值,而不是尝试将整个参数字符串编码为单个数据。输出编码的主要目的是消除用户使用他们提供的数据将“数据”上下文分解为“控制”上下文的可能性。
在您的示例中,字符串partner = 1& partner = 2对于解析器
看起来像这样<强>伙伴= 强> 1 的&安培;伙伴= 强> 2
(粗体是控件,斜体是数据) - 您只想编码字符串的数据上下文,因为不受信任的来源不提供控制上下文
如果您提供的用户数据为 1&amp; partner = 2 ,则您的编码字符串应如下所示
<强>伙伴= 强> 1%26partner = 2 的&安培;伙伴= 强> 2
另一个重要的注意事项是规范化用于将给定字符串简化为最基本格式 - 因此提供的字符串中的所有编码都将被解码,从而无法执行双重和混合编码攻击。
对您的问题的简短回答是单独编码参数的值,而不是编码整个URL参数字符串。
参考文献: