Security context
LowGHSA-q3rp-555r-hh6r CVE-2011-4344CWE-79Published May 17, 2022

Jenkins allows Cross-Site Scripting (XSS)

Research this vulnerability

Research is free — Hunters explains how the bug works, the root-cause code pattern, how the fix addresses it, and how to test whether a target is affected, in chat. Investigate & write exploit is a paid run — the engine reads the advisory and fix commits, then builds and validates a working proof-of-concept exploit with reproduction steps.

Affected versions

0 → fixed in 1.409.31.410 → fixed in 1.438

Details

Cross-site scripting (XSS) vulnerability in Jenkins Core in Jenkins before 1.438, and 1.409 LTS before 1.409.3 LTS, when a stand-alone container is used, allows remote attackers to inject arbitrary web script or HTML via vectors related to error messages.

The fix

escape error messages which are supposed be plain text and

Kohsuke Kawaguchi· Nov 2, 2011, 05:27 AM+192410ed3001d
src/java/winstone/ErrorServlet.java+1 1
@@ -42,7 +42,7 @@ public void service(ServletRequest request, ServletResponse response) throws Ser
// If we are here there was no error servlet, so show the default error page
String output = Launcher.RESOURCES.getString("WinstoneResponse.ErrorPage",
- new String[] { sc + "", (msg == null ? "" : msg), sw.toString(),
+ new String[] { sc + "", URIUtil.htmlEscape(msg == null ? "" : msg), URIUtil.htmlEscape(sw.toString()),
Launcher.RESOURCES.getString("ServerVersion"),
"" + new Date() });
response.setContentLength(output.getBytes(response.getCharacterEncoding()).length);
src/java/winstone/URIUtil.java+17 0
@@ -50,4 +50,21 @@ static String canonicalPath(String path) {
return buf.toString();
}
+ /**
+ * Performs necessary escaping to render arbitrary plain text as plain text without any markup.
+ */
+ public static String htmlEscape(String text) {
+ StringBuilder buf = new StringBuilder(text.length()+64);
+ for( int i=0; i<text.length(); i++ ) {
+ char ch = text.charAt(i);
+ if(ch=='<')
+ buf.append("&lt;");
+ else
+ if(ch=='&')
+ buf.append("&amp;");
+ else
+ buf.append(ch);
+ }
+ return buf.toString();
+ }
}
src/java/winstone/WinstoneResponse.java+1 1
@@ -805,7 +805,7 @@ public void sendError(int sc, String msg) throws IOException {
this.statusCode = sc;
}
String output = Launcher.RESOURCES.getString("WinstoneResponse.ErrorPage",
- new String[] { sc + "", (msg == null ? "" : msg), "",
+ new String[] { sc + "", URIUtil.htmlEscape(msg == null ? "" : msg), "",
Launcher.RESOURCES.getString("ServerVersion"),
"" + new Date() });
setContentLength(output.getBytes(getCharacterEncoding()).length);

References