Hi,

I've tried to write a patch for the very specific issue in this CVE.
The regex used is derived from the one used in redmine
(https://github.com/redmine/redmine/blob/master/lib/redcloth3.rb#L818).

Package built with this patch (in pbuilder) and succesfully tested against the
PoC in http://co3k.org/blog/redcloth-unfixed-xss-en

As a side note, I would not be able to patch redcloth for a more complex issue
or anything in the ragel layer.

Regards
Description: fix for CVE-2012-6684
Author: Cédric Barboiron <c...@winkie.fr>

--- a/lib/redcloth/formatters/html.rb
+++ b/lib/redcloth/formatters/html.rb
@@ -111,14 +111,17 @@
   end
   
   def link(opts)
-    "<a href=\"#{escape_attribute 
opts[:href]}\"#{pba(opts)}>#{opts[:name]}</a>"
+    href = escape_uri(escape_attribute(opts[:href]))
+    "<a href=\"#{href}\"#{pba(opts)}>#{opts[:name]}</a>"
   end
   
   def image(opts)
     opts.delete(:align)
     opts[:alt] = opts[:title]
-    img = "<img src=\"#{escape_attribute opts[:src]}\"#{pba(opts)} 
alt=\"#{escape_attribute opts[:alt].to_s}\" />"  
-    img = "<a href=\"#{escape_attribute opts[:href]}\">#{img}</a>" if 
opts[:href]
+    src = escape_uri(escape_attribute(opts[:src]))
+    href = escape_uri(escape_attribute(opts[:href])) if opts[:href]
+    img = "<img src=\"#{src}\"#{pba(opts)} alt=\"#{escape_attribute 
opts[:alt].to_s}\" />"
+    img = "<a href=\"#{href}\">#{img}</a>" if href
     img
   end
   
@@ -267,6 +270,22 @@
   def escape_attribute(text)
     html_esc(text, :html_escape_attributes)
   end
+
+  # fix for CVE-2012-6684
+  def escape_uri(uri)
+    # escape only if filter_html is enabled
+    return uri unless filter_html
+
+    # accept every scheme://*
+    # allow only mailto:*
+    # accept all other uri
+    m = %r{^([a-zA-Z]+):(?!//)}.match uri
+    return uri unless m && m[1] != 'mailto'
+
+    # unwanted uri (e.g. javascript:*)
+    # prefix by '#'
+    '#' << uri
+  end
   
   def after_transform(text)
     text.chomp!
--- a/spec/fixtures/filter_html.yml
+++ b/spec/fixtures/filter_html.yml
@@ -175,3 +175,18 @@
 ---
 in: /me <3 beer
 filtered_html: <p>/me &lt;3 beer</p>
+---
+name: CVE-2012-6684
+in: |-
+  ["clickme":javascript:alert(%27XSS%27)]
+filtered_html: <p><a href="#javascript:alert(%27XSS%27)">clickme</a></p>
+---
+name: legit http link
+in: |-
+  ["clickme":http://example.com]
+filtered_html: <p><a href="http://example.com";>clickme</a></p>
+---
+name: legit mailto link
+in: |-
+  ["clickme":mailto:u...@example.com]
+filtered_html: <p><a href="mailto:u...@example.com";>clickme</a></p>

Reply via email to