技术控

    今日:0| 主题:63445
收藏本版 (1)
最新软件应用技术尽在掌握

[其他] Fixing an XSS vulnerability in marked

[复制链接]
萌面超人 发表于 2016-10-5 01:30:17
168 2
Marked’s protection mechanisms

   While Markdown doesn’t support scripts, marked (like other Markdown clients) does support inline HTML. Inline HTML can include <script> tags, which can be used by attackers to inject malicious scripts. Since marked is often used to render user input back to the page, its authors added a security option to overcome this case. The package supports a sanitize option, which detects HTML and dangerous input and encodes or removes it.
   The sanitize option is (unfortunately) turned off by default, but you can turn it on in your app. The following example shows the sanitize option in action:
  1. var marked = require('marked');
  2. console.log(marked('<script>alert(1)</script>'));
  3. // Outputs: <script>alert(1)</script>
  4. marked.setOptions({ sanitize: true });
  5. console.log(marked('<script>alert(1)</script>'));
  6. // Outputs: <p><script>alert(1)</script></p>
复制代码
  Catching HTML is important, but sanitization doesn’t end there. While Markdown doesn’t support scripts, it does support links, which creates the potential for javascript links (e.g. javascript:alert(1) ) , which can cause damage when a user clicks them. The sanitize functionality is aware of this, and removes links starting with the javascript: protocol. It even removes links using the HTML entity for colons — e.g. javascript&58;alert(1) . Unfortunately, even with this awareness, they missed one vulnerability vector.
  The Vulnerability

   HTML is a very loose format, and browsers are very tolerant when processing it. An example of this tolerance is that, when processing HTML entities, browsers do not enforce the trailing colon, accepting both : and : . The sanitization in marked, on the other hand, requires the colon, and treats the text as simple text if it doesn’t find it. This means : will be removed, but &58this; will simply be passed along to the output. An attacker can use this technique to evade marked 's sanitizer while browsers still execute a script.
   Here’s a code illustration of where sanitize does and doesn’t work:
  1. var marked = require('marked');
  2. marked.setOptions({sanitize: true});
  3. // Naive attempt - fails.
  4. console.log(marked('[Gotcha](javascript:alert(1))'));
  5. // Outputs: <p>)</p>
  6. // Evasion attempt using ':' instead of ':' - fails.
  7. console.log(marked('[Gotcha](javascript:alert(1))'));
  8. // Outputs: <p></p>
  9. // Evasion attempt using ':this;' (note the 'this') instead of ':' - SUCCEEDS
  10. console.log(marked('[Gotcha](javascript:this;alert(1))'));
  11. // Outputs: <p><a href="javascript:this;alert(1)">Gotcha</a></p>
  12. // Same as: <p><a href="javascript:this;alert(1);">Gotcha</a></p>
复制代码
  The browser will interpret : the same as : , thus invoking the script on click. Of course, the script we included is quite pointless, but an attacker could inject a much more sophisticated payload, breaking the browser’s Same-Origin Policy and triggering the full damage XSS can cause.
  Live Exploit on a Sample Node.js application

   Nothing helps one appreciate a vulnerability better than exploiting it on real code. Therefore, I added this vulnerability to Snyk’s vulnerable demo application, Goof . You can clone Goof and get it running through the instructions on GitHub .
  Goof is a TODO application, and uses marked to support Markdown in its notes. Goof is a best-in-class TODO app, and such an app simply MUST support links, bold and italics!
   For instance, entering the TODO items Buy **beer** and [snyk](https://snyk.io/) would result in the expected bold and hyperlink like so:
     

Fixing an XSS vulnerability in marked

Fixing an XSS vulnerability in marked
      An amazingly feature-complete TODO app.      Next, let’s try to enter a malicious payload. The next screenshot shows the visual and DOM state after entering each of the three attack payloads above. Note that since this is a TODO list, the items are sorted by the date they were added, with the newest on top.
     

Fixing an XSS vulnerability in marked

Fixing an XSS vulnerability in marked
      Entering malicious payloads into the TODO app.       As you can see, the first two attempted attacks were mitigated by the sanitizer, reduced to <p>)</p> and <p></p> respectively. The last payload, however, successfully created a hyperlink which will invoke javascript:this;alert(1) . Executing this does nothing (simply references an existing variable), while the alert shows a popup.
  After making our exploit alert a bit clearer and clicking the link, we get this:
     

Fixing an XSS vulnerability in marked

Fixing an XSS vulnerability in marked
      Marked exploit was successful.       If you’d like to go through this attack flow yourself, install Goof locally and going through the exploit payloads under the exploits directory.
  How to Remediate?

   For a long while, there was no official version of marked that fixes the issue. The  marked  repository has been inactive since last summer, and the vulnerability was only disclosed later on. Open source maintenance is a tricky topic, as life circumstances or simply loss of interest can result in very slow updates - or even none at all.
   During the period where no fix was available, the only way to fix the issue was by applying a patch using Snyk’s Wizard . This patch was created by our security research team, and is based on Matt Austin ’s original pull request to the repository.
   Like all other Snyk patches, you can see the detailed patch files in our open source vulnerability database . There are actually 3 different patches for different versions of marked, the simplest of which being no more than this:
  1. function unescape(html) {
  2. -   return html.replace(/&([#\w]+);/g, function(_, n) {
  3. +   // explicitly match decimal, hex, and named HTML entities
  4. +   return html.replace(/&(#(?:\d+)|(?:#x[0-9A-Fa-f]+)|(?:\w+));?/g, function(_, n) {
复制代码
  In late July, however, marked’s authors did release a new version, acknowledging the importance of fixing this issue. And so, if you’re using marked today and are able to, you can also fix this issue by upgrading to version 0.3.6 .
  Summary & Recommendations

   This XSS vulnerability on marked is a high severity security issue in a popular package, and so it’s important that you ensure you address it if you’re using the marked package yourself.
  In addition, it serves as a good example for several broader issues:
  
       
  • How tricky it is to sanitize complex user input. HTML, SQL and URL encoding are very hard to get completely right, and attackers only need one loophole to get in. If possible, always prefer whitelisting allowed values over blacklisting through pattern matching.   
  • The risks third party dependencies carry for your application. It’s important to stay on top of known vulnerabilities in npm dependencies.   
  • Why open source maintenance is a complicated topic, and how it can have very real and urgent implications.  
景晓丽 发表于 2016-10-5 04:26:09
学海无涯,回头是岸!  
回复 支持 反对

使用道具 举报

她的枕头 发表于 2016-10-5 04:47:04
好贴,好贴,必须顶一个!
回复 支持 反对

使用道具 举报

我要投稿

推荐阅读


回页顶回复上一篇下一篇回列表
手机版/c.CoLaBug.com ( 粤ICP备05003221号 | 粤公网安备 44010402000842号 )

© 2001-2017 Comsenz Inc.

返回顶部 返回列表