From ffa87887ee0517793df7541629a470e331f9fe60 Mon Sep 17 00:00:00 2001
From: Eric Hodel <drbrain@segment7.net>
Date: Tue, 5 Feb 2013 19:57:58 -0800
Subject: [PATCH] Fix CVE-2013-0256, an XSS exploit in RDoc

See CVE-2013-0256 for details on the exploit including a patch you can
apply to generated RDoc output.
---
 CVE-2013-0256.rdoc                                 |   49 ++++++++++++++++++++
 History.rdoc                                       |    5 +-
 Manifest.txt                                       |    1 +
 Rakefile                                           |    1 +
 lib/rdoc.rb                                        |    2 +-
 .../generator/template/darkfish/js/darkfish.js     |   16 ++++---
 6 files changed, 65 insertions(+), 9 deletions(-)
 create mode 100644 CVE-2013-0256.rdoc

Index: CVE-2013-0256.rdoc
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ CVE-2013-0256.rdoc	2013-02-13 18:12:59.016554966 +0100
@@ -0,0 +1,49 @@
+= RDoc 2.3.0 through 3.12 XSS Exploit
+
+RDoc documentation generated by rdoc 2.3.0 through rdoc 3.12 and prereleases up
+to rdoc 4.0.0.preview2.1 are vulnerable to an XSS exploit.  This exploit may
+lead to cookie disclosure to third parties.
+
+The exploit exists in darkfish.js which is copied from the RDoc install
+location to the generated documentation.
+
+RDoc is a static documentation generation tool.  Patching the library itself
+is insufficient to correct this exploit.  Those hosting rdoc documentation will
+need to apply the following patch.  If applied while ignoring whitespace, this
+patch will correct all affected versions:
+
+  diff --git darkfish.js darkfish.js
+  index 4be722f..f26fd45 100644
+  --- darkfish.js
+  +++ darkfish.js
+  @@ -109,13 +109,15 @@ function hookSearch() {
+   function highlightTarget( anchor ) {
+     console.debug( "Highlighting target '%s'.", anchor );
+   
+  -  $("a[name=" + anchor + "]").each( function() {
+  -    if ( !$(this).parent().parent().hasClass('target-section') ) {
+  -      console.debug( "Wrapping the target-section" );
+  -      $('div.method-detail').unwrap( 'div.target-section' );
+  -      $(this).parent().wrap( '<div class="target-section"></div>' );
+  -    } else {
+  -      console.debug( "Already wrapped." );
+  +  $("a[name]").each( function() {
+  +    if ( $(this).attr("name") == anchor ) {
+  +      if ( !$(this).parent().parent().hasClass('target-section') ) {
+  +        console.debug( "Wrapping the target-section" );
+  +        $('div.method-detail').unwrap( 'div.target-section' );
+  +        $(this).parent().wrap( '<div class="target-section"></div>' );
+  +      } else {
+  +        console.debug( "Already wrapped." );
+  +      }
+       }
+     });
+   };
+
+RDoc 3.9.5, 3.12.1 and RDoc 4.0.0.rc.2 and newer are not vulnerable to this
+exploit.
+
+This exploit was discovered by Evgeny Ermakov <corwmh@gmail.com>.
+
+This vulnerability has been assigned the CVE identifier CVE-2013-0256.
+
Index: lib/rdoc/generator/template/darkfish/js/darkfish.js
===================================================================
--- lib/rdoc/generator/template/darkfish/js/darkfish.js.orig	2013-02-13 18:08:59.057573129 +0100
+++ lib/rdoc/generator/template/darkfish/js/darkfish.js	2013-02-13 18:12:59.017554966 +0100
@@ -73,13 +73,15 @@ function hookQuickSearch() {
 function highlightTarget( anchor ) {
 	console.debug( "Highlighting target '%s'.", anchor );
 
-	$("a[name=" + anchor + "]").each( function() {
-		if ( !$(this).parent().parent().hasClass('target-section') ) {
-			console.debug( "Wrapping the target-section" );
-			$('div.method-detail').unwrap( 'div.target-section' );
-			$(this).parent().wrap( '<div class="target-section"></div>' );
-		} else {
-			console.debug( "Already wrapped." );
+  $("a[name]").each( function() {
+    if ( $(this).attr("name") == anchor ) {
+      if ( !$(this).parent().parent().hasClass('target-section') ) {
+        console.debug( "Wrapping the target-section" );
+        $('div.method-detail').unwrap( 'div.target-section' );
+        $(this).parent().wrap( '<div class="target-section"></div>' );
+      } else {
+        console.debug( "Already wrapped." );
+      }
 		}
 	});
 };
