Skip to content

Commit

Permalink
JCR-3950: fix XSS vulnerability in DirListingExportHandler (ported to…
Browse files Browse the repository at this point in the history
… 2.0)

git-svn-id: https://svn.apache.org/repos/asf/jackrabbit/branches/2.0@1732470 13f79535-47bb-0310-9956-ffa450edef68
  • Loading branch information
reschke committed Feb 26, 2016
1 parent e8cf4b5 commit 6f5429b
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 21 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -210,13 +210,28 @@ public static String replace(String text, String oldString, String newString) {
}

/**
* Replaces illegal XML characters in the given string by their corresponding
* predefined entity references.
* Replaces XML characters in the given string that might need escaping
* as XML text or attribute
*
* @param text text to be escaped
* @return a string
*/
public static String encodeIllegalXMLCharacters(String text) {
return encodeMarkupCharacters(text, false);
}

/**
* Replaces HTML characters in the given string that might need escaping
* as HTML text or attribute
*
* @param text text to be escaped
* @return a string
*/
public static String encodeIllegalHTMLCharacters(String text) {
return encodeMarkupCharacters(text, true);
}

private static String encodeMarkupCharacters(String text, boolean isHtml) {
if (text == null) {
throw new IllegalArgumentException("null argument");
}
Expand Down Expand Up @@ -251,7 +266,7 @@ public static String encodeIllegalXMLCharacters(String text) {
} else if (ch == '"') {
buf.append(""");
} else if (ch == '\'') {
buf.append("'");
buf.append(isHtml ? "'" : "'");
}
}
if (buf == null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -189,4 +189,11 @@ public void testEscapeIllegalJcrChars() throws Exception {
assertEquals("local'name", Text.escapeIllegalJcrChars("local'name"));
assertEquals("local\"name", Text.escapeIllegalJcrChars("local\"name"));
}
public void testEscapeXML() {
assertEquals("&amp;&lt;&gt;&apos;&quot;", Text.encodeIllegalXMLCharacters("&<>'\""));
}

public void testEscapeHTML() {
assertEquals("&amp;&lt;&gt;&#39;&quot;", Text.encodeIllegalHTMLCharacters("&<>'\""));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -145,14 +145,14 @@ public boolean exportContent(ExportContext context, boolean isCollection) throws
String repURL = rep.getDescriptor(Repository.REP_VENDOR_URL_DESC);
String repVersion = rep.getDescriptor(Repository.REP_VERSION_DESC);
writer.print("<html><head><title>");
writer.print(repName);
writer.print(Text.encodeIllegalHTMLCharacters(repName));
writer.print(" ");
writer.print(repVersion);
writer.print(Text.encodeIllegalHTMLCharacters(repVersion));
writer.print(" ");
writer.print(item.getPath());
writer.print(Text.encodeIllegalHTMLCharacters(item.getPath()));
writer.print("</title></head>");
writer.print("<body><h2>");
writer.print(item.getPath());
writer.print(Text.encodeIllegalHTMLCharacters(item.getPath()));
writer.print("</h2><ul>");
writer.print("<li><a href=\"..\">..</a></li>");
if (item.isNode()) {
Expand All @@ -161,21 +161,21 @@ public boolean exportContent(ExportContext context, boolean isCollection) throws
Node child = iter.nextNode();
String label = Text.getName(child.getPath());
writer.print("<li><a href=\"");
writer.print(Text.escape(label));
writer.print(Text.encodeIllegalHTMLCharacters(Text.escape(label)));
if (child.isNode()) {
writer.print("/");
}
writer.print("\">");
writer.print(Text.encodeIllegalXMLCharacters(label));
writer.print(Text.encodeIllegalHTMLCharacters(label));
writer.print("</a></li>");
}
}
writer.print("</ul><hr size=\"1\"><em>Powered by <a href=\"");
writer.print(repURL);
writer.print(Text.encodeIllegalHTMLCharacters(repURL));
writer.print("\">");
writer.print(repName);
writer.print(Text.encodeIllegalHTMLCharacters(repName));
writer.print("</a> version ");
writer.print(repVersion);
writer.print(Text.encodeIllegalHTMLCharacters(repVersion));
writer.print("</em></body></html>");
} catch (RepositoryException e) {
// should not occur
Expand Down Expand Up @@ -209,32 +209,32 @@ public boolean exportContent(ExportContext context, DavResource resource) throws
String repURL = rep.getDescriptor(Repository.REP_VENDOR_URL_DESC);
String repVersion = rep.getDescriptor(Repository.REP_VERSION_DESC);
writer.print("<html><head><title>");
writer.print(repName);
writer.print(Text.encodeIllegalHTMLCharacters(repName));
writer.print(" ");
writer.print(repVersion);
writer.print(Text.encodeIllegalHTMLCharacters(repVersion));
writer.print(" ");
writer.print(resource.getResourcePath());
writer.print(Text.encodeIllegalHTMLCharacters(resource.getResourcePath()));
writer.print("</title></head>");
writer.print("<body><h2>");
writer.print(resource.getResourcePath());
writer.print(Text.encodeIllegalHTMLCharacters(resource.getResourcePath()));
writer.print("</h2><ul>");
writer.print("<li><a href=\"..\">..</a></li>");
DavResourceIterator iter = resource.getMembers();
while (iter.hasNext()) {
DavResource child = iter.nextResource();
String label = Text.getName(child.getResourcePath());
writer.print("<li><a href=\"");
writer.print(child.getHref());
writer.print(Text.encodeIllegalHTMLCharacters(child.getHref()));
writer.print("\">");
writer.print(Text.encodeIllegalXMLCharacters(label));
writer.print(Text.encodeIllegalHTMLCharacters(label));
writer.print("</a></li>");
}
writer.print("</ul><hr size=\"1\"><em>Powered by <a href=\"");
writer.print(repURL);
writer.print(Text.encodeIllegalHTMLCharacters(repURL));
writer.print("\">");
writer.print(repName);
writer.print(Text.encodeIllegalHTMLCharacters(repName));
writer.print("</a> version ");
writer.print(repVersion);
writer.print(Text.encodeIllegalHTMLCharacters(repVersion));
writer.print("</em></body></html>");
} catch (RepositoryException e) {
// should not occur
Expand Down

0 comments on commit 6f5429b

Please sign in to comment.