2014-10-30 29 views
1

防止XSS攻击的一种常用技术是在将不可信数据显示在HTML页面上之前进行编码。在页面内部可以出现不同的上下文,每个都需要不同的编码。在客户端对XSS使用输出编码是否安全?

对服务器端的响应进行编码没有任何意义,因为在这一层,我们不知道数据将在HTML页面的什么位置出现。

因此,在客户端进行编码是方便和合理的。问题是如果它是安全的。第一印象是听起来不安全,因为攻击者可以修改客户端代码(比如说JavaScript)。但是当您考虑它时,修改的代码将只能用于攻击者的浏览器。该网站的其他访问者不会受到这些更改的影响。

它仍然安全或我错过了什么?

回答

3

理论上,编码客户端不会比编码服务器端更危险。确保安全的关键在于你在所有渲染数据的地方使用合适的编码。您当然可以创建一个良好的实现来在客户端和服务器端安全地呈现用户提交的数据。实际上,实现输出编码客户端的一个缺点是潜在的攻击者可以很容易地检查你的源代码是否存在缺陷。这意味着如果客户端编码实现中存在缺陷,那么比服务器端更容易找到(假设是封闭的源系统)。如果你正在开发开源软件,那么这一点是没有意义的。

同样如您所说,修改您的客户端编码代码的攻击者并不是问题,因为他们只会修改自己的代码副本,不会影响其他访问者。

IMO它实际上更清洁,让客户端处理编码,特别是如果您正在开发一个由Web和原生移动应用程序共享的API。您不希望您的移动应用程序必须将HTML编码值转换回原始格式。

2

在服务器端与XSS战斗并不像您想象的那么困难。目标是知道你应该在哪个上下文中编码哪个字符。

基本上有4种不同的情况,我们应该考虑XSS。

HTML语境

如果你想获得XSS在这种情况下,你需要<和>字符攻击。因此只编码这两个字符可以解决基于HTML上下文的XSS。

/** 
    * XSS protection function for HTML context only 
    * @usecases 
    * <title>use this function if output reflects here or as a content of any HTML tag.</title> 
    * e.g., <span>use this function if output reflects here</span> 
    * e.g., <div>use this function if output reflects here</div> 
    * @description 
    * Sanitize/Filter <and> so that attacker can not leverage them for JavaScript execution. 
    * @author Ashar Javed 
    * @Link https://twitter.com/soaj1664ashar 
    * @demo http://xssplaygroundforfunandlearn.netai.net/final.html 
    */ 
    function htmlContextCleaner($input) { 
     $bad_chars = array("<", ">"); 
     $safe_chars = array("&lt;", "&gt;"); 
     $output = str_replace($bad_chars, $safe_chars, $input); 
     return stripslashes($output); 
    } 

的Javascript语境

最常见的情况是类似以下代码。

<script> var name = 'USERINPUTISHERE';</script> 

<script> var name = "USERINPUTISHERE";</script> 

<button type="submit" onclick="return callSomeFunction('USERINPUTHERE')"> 

为了防止你对JS基于上下文XSS攻击的应用程序。你需要编码6个特定的字符。请阅读以下说明以了​​解脚本上下文的攻击媒介。

/** 
* XSS protection function for script context only 
* @usecases 
* @double quoted case e.g., 
* <script> var searchquery = "use this function if output reflects here"; </script> 
* @single quoted case e.g., 
* <script> var searchquery = 'use this function if output reflects here'; </script> 
* @description 
* Sanitize/Filter meta or control characters that attacker may use to break the context e.g., 
* "; confirm(1); " OR '; prompt(1); // OR </script><script>alert(1)</script> 
* \ and % are filtered because they may break the page e.g., \n or %0a 
* & is sanitized because of complex or nested context (if in use) 
* @author Ashar Javed 
* @Link https://twitter.com/soaj1664ashar 
* @demo http://xssplaygroundforfunandlearn.netai.net/final.html 
*/ 
function scriptContextCleaner($input) { 
    $bad_chars = array("\"", "<", "'", "\\\\", "%", "&"); 
    $safe_chars = array("&quot;", "&lt;", "&apos;", "&bsol;", "&percnt;", "&amp;"); 
    $output = str_replace($bad_chars, $safe_chars, $input); 
    return stripslashes($output); 
} 

属性上下文

以下代码可以是例如用于属性上下文。

<input name="fname" value="USERINPUTISHERE"> 

或样例的单引号形式。

<input name='fname' value='USERINPUTISHERE'> 

基本上我们需要编码非常特殊的字符才能保证它的安全。我们还需要编码back-tick,以便为旧版本的IE提供安全的上下文。请阅读以下说明和代码。

/** 
    * XSS protection function for an attribute context only 
    * @usecases 
    * @double quoted case e.g., 
    * <div class="use this function if output reflects here">attribute context</div> 
    * In above example class attribute have been used but it can be any like id or alt etc. 
    * @single quoted case e.g., 
    * <input type='text' value='use this function if output reflects here'> 
    * @description 
    * Sanitize/Filter meta or control characters that attacker may use to break the context e.g., 
    * "onmouseover="alert(1) OR 'onfocus='confirm(1) OR ``onmouseover=prompt(1) 
    * back-tick i.e., `` is filtered because old IE browsers treat it as a valid separator. 
    * @author Ashar Javed 
    * @Link https://twitter.com/soaj1664ashar 
    * @demo http://xssplaygroundforfunandlearn.netai.net/final.html 
    */ 
    function attributeContextCleaner($input) { 
     $bad_chars = array("\"", "'", "``"); 
     $safe_chars = array("&quot;", "&apos;", "&grave;"); 
     $output = str_replace($bad_chars, $safe_chars, $input); 
     return stripslashes($output); 
    } 

样式上下文

作为一个攻击者,得到XSS与通常与IE样式上下文。请再次阅读以下说明和代码。

/** 
* XSS protection function for style context only 
* @usecases 
* @double quoted case e.g., 
* <span style="use this function if output reflects here"></span> 
* @single quoted case e.g., 
* <div style='use this function if output reflects here'></div> 
* OR <style>use this function if output reflects here</style> 
* @description 
* Sanitize/Filter meta or control characters that attacker may use to execute JavaScript e.g., 
* (is filtered because width:expression(alert(1)) 
* & is filtered in order to stop decimal + hex + HTML5 entity encoding 
* < is filtered in case developers are using <style></style> tags instead of style attribute. 
* < is filtered because attacker may close the </style> tag and then execute JavaScript. 
* The function allows simple styles e.g., color:red, height:100px etc. 
* @author Ashar Javed 
* @Link https://twitter.com/soaj1664ashar 
* @demo http://xssplaygroundforfunandlearn.netai.net/final.html 
*/ 
function styleContextCleaner($input) { 
    $bad_chars = array("\"", "'", "``", "(", "\\\\", "<", "&"); 
    $safe_chars = array("&quot;", "&apos;", "&grave;", "&lpar;", "&bsol;", "&lt;", "&amp;"); 
    $output = str_replace($bad_chars, $safe_chars, $input); 
    return stripslashes($output); 
} 

结论

与XSS服务器端编码战斗,如果你知道哪些字符在他们的特殊背景下进行编码时可以很容易。当您使用back tick(`)作为属性分隔符(如下所示)时,只有一个复杂因素。

<input name=`fname` value=`USERINPUTHERE`> 

此功能无法保护您的应用程序。但我还没有看到这个案例的真实生活的例子!

我在上面描述的方法是针对数十名黑客/安全研究人员进行测试的,没有人利用它。 (详情:https://twitter.com/soaj1664ashar/status/478939711667712000)。另外Symphonycms使用这种方法来预防XSS(也可以从他们的回购中获取所有代码示例)

正如你所看到的,你需要知道变量会反映哪个位置。通常,开发人员知道变量的输出位置,但是如果您确实不知道DOMPurify对您更有用,但我相信这可能会导致代码复杂性并难以维护。

DOMPurify

DOMPurify是DOM-只,速度超快,超级容错XSS消毒剂对HTML,MathML和SVG。它采用JavaScript编写,适用于所有现代浏览器(Safari,Opera(15+),Internet Explorer(9+),Firefox和Chrome)以及其他几乎所有使用Blink或WebKit的软件。它不会在IE6或其他旧版浏览器上中断。它根本没有做任何事情。

DOMPurify是由在Web攻击和XSS方面拥有丰富背景的安全人员撰写的。不要害怕。

更多信息可以在这里找到(https://github.com/cure53/DOMPurify

相关问题