Author: bodewig
Date: Mon Jun 24 15:12:57 2013
New Revision: 1496083
URL: http://svn.apache.org/r1496083
Log:
post-process generated javadocs as workaround for CVE-2013-1571 - based on
Maven patch by Uwe Schindler - PR 55132
Added:
ant/core/trunk/src/resources/org/apache/tools/ant/taskdefs/
ant/core/trunk/src/resources/org/apache/tools/ant/taskdefs/javadoc-frame-injections-fix.txt
(with props)
Modified:
ant/core/trunk/CONTRIBUTORS
ant/core/trunk/WHATSNEW
ant/core/trunk/contributors.xml
ant/core/trunk/manual/Tasks/javadoc.html
ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/Javadoc.java
Modified: ant/core/trunk/CONTRIBUTORS
URL:
http://svn.apache.org/viewvc/ant/core/trunk/CONTRIBUTORS?rev=1496083&r1=1496082&r2=1496083&view=diff
==============================================================================
--- ant/core/trunk/CONTRIBUTORS (original)
+++ ant/core/trunk/CONTRIBUTORS Mon Jun 24 15:12:57 2013
@@ -364,6 +364,7 @@ Tom May
Tomasz Bech
Trejkaz Xaoza
Ulrich Schmidt
+Uwe Schindler
Valentino Miazzo
Victor Toni
Vimil Saju
Modified: ant/core/trunk/WHATSNEW
URL:
http://svn.apache.org/viewvc/ant/core/trunk/WHATSNEW?rev=1496083&r1=1496082&r2=1496083&view=diff
==============================================================================
--- ant/core/trunk/WHATSNEW (original)
+++ ant/core/trunk/WHATSNEW Mon Jun 24 15:12:57 2013
@@ -23,6 +23,15 @@ Fixed bugs:
Other changes:
--------------
+ * <javadoc> will now post-process the generated in order to mitigate
+ the frame injection attack possible in javadocs generated by Oracle
+ JDKs prior to Java7 Update 25. The vulnerability is known as
+ CVE-2013-1571.
+ There is an option to turn off the post-processing but it is only
+ recommended you do so if all your builds use a JDK that's not
+ vulnerable.
+ Bugzilla Report 55132.
+
Changes from Ant 1.9.0 TO Ant 1.9.1
===================================
Modified: ant/core/trunk/contributors.xml
URL:
http://svn.apache.org/viewvc/ant/core/trunk/contributors.xml?rev=1496083&r1=1496082&r2=1496083&view=diff
==============================================================================
--- ant/core/trunk/contributors.xml (original)
+++ ant/core/trunk/contributors.xml Mon Jun 24 15:12:57 2013
@@ -1461,6 +1461,10 @@
<last>Schmidt</last>
</name>
<name>
+ <first>Uwe</first>
+ <last>Schindler</last>
+ </name>
+ <name>
<first>Valentino</first>
<last>Miazzo</last>
</name>
Modified: ant/core/trunk/manual/Tasks/javadoc.html
URL:
http://svn.apache.org/viewvc/ant/core/trunk/manual/Tasks/javadoc.html?rev=1496083&r1=1496082&r2=1496083&view=diff
==============================================================================
--- ant/core/trunk/manual/Tasks/javadoc.html (original)
+++ ant/core/trunk/manual/Tasks/javadoc.html Mon Jun 24 15:12:57 2013
@@ -509,6 +509,18 @@ to <javadoc> using <tt>classpath</
<td align="center" valign="top">1.4</td>
<td align="center" valign="top">No</td>
</tr>
+ <tr>
+ <td valign="top">postProcessGeneratedJavadocs</td>
+ <td valign="top">Whether to post-process the generated javadocs in
+ order to mitigate CVE-2013-1571. Defaults to true. <em>Since Ant
+ 1.9.2</em><br></td>
+ There is a frame injection attack possible in javadocs generated by Oracle
+ JDKs prior to Java7 Update 25. When this flag is set to true, Ant
+ will check whether the docs are vulnerable and will try to fix them.
+ </td>
+ <td align="center" valign="top">1.4</td>
+ <td align="center" valign="top">No</td>
+ </tr>
</table>
<h4><a name="groupattribute">Format of the group attribute</a></h4>
Modified: ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/Javadoc.java
URL:
http://svn.apache.org/viewvc/ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/Javadoc.java?rev=1496083&r1=1496082&r2=1496083&view=diff
==============================================================================
--- ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/Javadoc.java
(original)
+++ ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/Javadoc.java Mon Jun
24 15:12:57 2013
@@ -17,13 +17,20 @@
*/
package org.apache.tools.ant.taskdefs;
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.FileReader;
import java.io.FileWriter;
import java.io.FilenameFilter;
import java.io.IOException;
-import java.io.BufferedWriter;
-import java.io.BufferedReader;
-import java.io.FileReader;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
@@ -50,6 +57,7 @@ import org.apache.tools.ant.types.Resour
import org.apache.tools.ant.types.ResourceCollection;
import org.apache.tools.ant.types.resources.FileProvider;
import org.apache.tools.ant.util.FileUtils;
+import org.apache.tools.ant.util.StringUtils;
import org.apache.tools.ant.util.JavaEnvUtils;
/**
@@ -81,6 +89,9 @@ public class Javadoc extends Task {
private static final boolean JAVADOC_5 =
!JavaEnvUtils.isJavaVersion(JavaEnvUtils.JAVA_1_4);
+ private static final String LOAD_FRAME = "function loadFrames() {";
+ private static final int LOAD_FRAME_LEN = LOAD_FRAME.length();
+
/**
* Inner class used to manage doclet parameters.
*/
@@ -452,6 +463,8 @@ public class Javadoc extends Task {
private String executable = null;
private boolean docFilesSubDirs = false;
private String excludeDocFilesSubDir = null;
+ private String docEncoding = null;
+ private boolean postProcessGeneratedJavadocs = true;
private ResourceCollectionContainer nestedSourceFiles
= new ResourceCollectionContainer();
@@ -1151,6 +1164,7 @@ public class Javadoc extends Task {
public void setDocencoding(String enc) {
cmd.createArgument().setValue("-docencoding");
cmd.createArgument().setValue(enc);
+ docEncoding = enc;
}
/**
@@ -1656,6 +1670,14 @@ public class Javadoc extends Task {
}
/**
+ * Whether to post-process the generated javadocs in order to mitigate
CVE-2013-1571.
+ * @since Ant 1.9.2
+ */
+ public void setPostProcessGeneratedJavadocs(boolean b) {
+ postProcessGeneratedJavadocs = b;
+ }
+
+ /**
* Execute the task.
* @throws BuildException on error
*/
@@ -1765,6 +1787,7 @@ public class Javadoc extends Task {
throw new BuildException("Javadoc returned " + ret,
getLocation());
}
+ postProcessGeneratedJavadocs();
} catch (IOException e) {
throw new BuildException("Javadoc failed: " + e, e, getLocation());
} finally {
@@ -2420,6 +2443,88 @@ public class Javadoc extends Task {
}
}
+ private void postProcessGeneratedJavadocs() throws IOException {
+ if (!postProcessGeneratedJavadocs) {
+ return;
+ }
+ final String fixData;
+ final InputStream in = getClass()
+ .getResourceAsStream("javadoc-frame-injections-fix.txt");
+ if (in == null) {
+ throw new FileNotFoundException("Missing resource "
+ +
"'javadoc-frame-injections-fix.txt' in "
+ + "classpath.");
+ }
+ try {
+ fixData = FileUtils.readFully(new InputStreamReader(in,
"US-ASCII")).trim()
+ .replace("\r\n", StringUtils.LINE_SEP)
+ .replace("\n", StringUtils.LINE_SEP);
+ } finally {
+ FileUtils.close(in);
+ }
+
+ final DirectoryScanner ds = new DirectoryScanner();
+ ds.setBasedir(destDir);
+ ds.setCaseSensitive(false);
+ ds.setIncludes(new String[] {
+ "**/index.html", "**/index.htm", "**/toc.html", "**/toc.htm"
+ });
+ ds.addDefaultExcludes();
+ ds.scan();
+ int patched = 0;
+ for (String f : ds.getIncludedFiles()) {
+ patched += postProcess(new File(destDir, f), fixData);
+ }
+ if (patched > 0) {
+ log("Patched " + patched + " link injection vulnerable javadocs",
+ Project.MSG_INFO);
+ }
+ }
+
+ private int postProcess(File file, String fixData) throws IOException {
+ String enc = docEncoding != null ? docEncoding
+ : FILE_UTILS.getDefaultEncoding();
+ // we load the whole file as one String (toc/index files are
+ // generally small, because they only contain frameset declaration):
+ InputStream fin = new FileInputStream(file);
+ String fileContents;
+ try {
+ fileContents =
+ FileUtils.safeReadFully(new InputStreamReader(fin, enc));
+ } finally {
+ FileUtils.close(fin);
+ }
+
+ // check if file may be vulnerable because it was not
+ // patched with "validURL(url)":
+ if (fileContents.indexOf("function validURL(url) {") < 0) {
+ // we need to patch the file!
+ String patchedFileContents = patchContent(fileContents, fixData);
+ if (!patchedFileContents.equals(fileContents)) {
+ FileOutputStream fos = new FileOutputStream(file);
+ try {
+ OutputStreamWriter w = new OutputStreamWriter(fos, enc);
+ w.write(patchedFileContents);
+ w.close();
+ return 1;
+ } finally {
+ FileUtils.close(fos);
+ }
+ }
+ }
+ return 0;
+ }
+
+ private String patchContent(String fileContents, String fixData) {
+ // using regexes here looks like overkill
+ int start = fileContents.indexOf(LOAD_FRAME);
+ if (start >= 0) {
+ return fileContents.substring(0, start) + fixData
+ + fileContents.substring(start + LOAD_FRAME_LEN);
+ }
+ return fileContents;
+ }
+
private class JavadocOutputStream extends LogOutputStream {
JavadocOutputStream(int level) {
super(Javadoc.this, level);
Added:
ant/core/trunk/src/resources/org/apache/tools/ant/taskdefs/javadoc-frame-injections-fix.txt
URL:
http://svn.apache.org/viewvc/ant/core/trunk/src/resources/org/apache/tools/ant/taskdefs/javadoc-frame-injections-fix.txt?rev=1496083&view=auto
==============================================================================
---
ant/core/trunk/src/resources/org/apache/tools/ant/taskdefs/javadoc-frame-injections-fix.txt
(added)
+++
ant/core/trunk/src/resources/org/apache/tools/ant/taskdefs/javadoc-frame-injections-fix.txt
Mon Jun 24 15:12:57 2013
@@ -0,0 +1,37 @@
+ if (targetPage != "" && !validURL(targetPage))
+ targetPage = "undefined";
+ function validURL(url) {
+ var pos = url.indexOf(".html");
+ if (pos == -1 || pos != url.length - 5)
+ return false;
+ var allowNumber = false;
+ var allowSep = false;
+ var seenDot = false;
+ for (var i = 0; i < url.length - 5; i++) {
+ var ch = url.charAt(i);
+ if ('a' <= ch && ch <= 'z' ||
+ 'A' <= ch && ch <= 'Z' ||
+ ch == '$' ||
+ ch == '_') {
+ allowNumber = true;
+ allowSep = true;
+ } else if ('0' <= ch && ch <= '9'
+ || ch == '-') {
+ if (!allowNumber)
+ return false;
+ } else if (ch == '/' || ch == '.') {
+ if (!allowSep)
+ return false;
+ allowNumber = false;
+ allowSep = false;
+ if (ch == '.')
+ seenDot = true;
+ if (ch == '/' && seenDot)
+ return false;
+ } else {
+ return false;
+ }
+ }
+ return true;
+ }
+ function loadFrames() {
Propchange:
ant/core/trunk/src/resources/org/apache/tools/ant/taskdefs/javadoc-frame-injections-fix.txt
------------------------------------------------------------------------------
svn:eol-style = native