Skip to content

Commit d3fd6a7

Browse files
committed
Migrate JS and attribute to HtmlView
1 parent cf256c3 commit d3fd6a7

File tree

5 files changed

+127
-27
lines changed

5 files changed

+127
-27
lines changed
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,17 @@
11
package net.krvtz.resources;
22

3+
import net.krvtz.views.HtmlView;
4+
35
import javax.ws.rs.*;
46
import javax.ws.rs.core.MediaType;
5-
import javax.ws.rs.core.Response;
67

78
@Path("/attr-xss")
89
@Produces({MediaType.TEXT_HTML})
910
@Consumes({MediaType.MULTIPART_FORM_DATA})
1011
public class AttrXssResource {
1112

12-
static final String MODULE = "AttrXssResource";
13-
1413
@GET
15-
public Response handle(@QueryParam("input") String input) {
16-
// TODO: switch to https://github.com/spullara/mustache.java
17-
18-
String response = "<html><head><title>" + MODULE + "</title></head>" +
19-
"<body><h1>" + MODULE + "</h1><div class=\"" + input + "\">div contents</div>" +
20-
"<form><input name=input></form>" +
21-
"</body></html>";
22-
// The X-Xss-Protection header is disabled to prevent the XSS vector being blocked by the
23-
// browser's built-in xSS auditor
24-
return Response.ok(response).encoding("utf-8").header("X-Xss-Protection", "0").build();
14+
public HtmlView handle(@QueryParam("input") String input) {
15+
return new HtmlView("/AttrXss.ftl.html", input);
2516
}
2617
}
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,16 @@
11
package net.krvtz.resources;
22

3+
import net.krvtz.views.HtmlView;
4+
35
import javax.ws.rs.*;
46
import javax.ws.rs.core.MediaType;
5-
import javax.ws.rs.core.Response;
67

78
@Path("/js-xss")
89
@Produces({MediaType.TEXT_HTML})
910
@Consumes({MediaType.MULTIPART_FORM_DATA})
1011
public class JsXssResource {
11-
static final String MODULE = "JsXssResource";
12-
1312
@GET
14-
public Response handle(@QueryParam("input") String input) {
15-
String response = "<html><head><title>" + MODULE + "</title></head>" +
16-
"<body><h1>" + MODULE + "</h1><div id=output>original div contents</div>" +
17-
"<script>var test=\"" + input + "\"; document.getElementById(\"output\").innerText=test;</script>" +
18-
"<form><input name=input></form>" +
19-
"</body></html>";
20-
// The X-Xss-Protection header is disabled to prevent the XSS vector being blocked by the
21-
// browser's built-in xSS auditor
22-
return Response.ok(response).encoding("utf-8").header("X-Xss-Protection", "0").build();
13+
public HtmlView handle(@QueryParam("input") String input) {
14+
return new HtmlView("/JsXss.ftl.html", input);
2315
}
24-
2516
}

src/main/resources/AttrXss.ftl.html

+54
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
<html>
2+
<head>
3+
<meta charset="utf-8"/>
4+
<title>TagEscapeResource</title>
5+
<meta content="width=device-width, initial-scale=1, shrink-to-fit=no" name="viewport">
6+
<link href="/app/assets/node_modules/bootstrap/dist/css/bootstrap.min.css" rel="stylesheet">
7+
</head>
8+
<body>
9+
10+
<main class="container" role="main">
11+
<h1>HTML attribute XSS</h1>
12+
13+
<p>This views is vulnerable to a XSS by injection into a HTML attribute.</p>
14+
15+
<!-- this sink has Freemarker auto-escaping explicitly disabled and should cause an XSS -->
16+
<div class="${content?no_esc}"></div>
17+
<p>Input=<code>${content}</code></p>
18+
19+
<form>
20+
<div class="form-group">
21+
<!-- this sink does not disable auto-escaping and should be safe -->
22+
<input class="form-control" name=input placeholder="%22><script>alert(1)</script>" value="${content}">
23+
</div>
24+
<input class="btn btn-primary" type="submit">
25+
</form>
26+
</main>
27+
28+
<div class="container">
29+
<div class="row">
30+
<div class="col">
31+
<h2>Sample XSS vectors</h2>
32+
33+
<p>All the regular XSS will work if preceded by <code>%22&gt;</code> to break from the HTML
34+
attribute context.</p>
35+
36+
<pre>
37+
"&gt;&lt;script&gt;alert(1)&lt;/script&gt;
38+
"&gt;&lt;img src=x onerror=alert(1)&gt;
39+
"&gt;&lt;video&gt;&lt;source onerror=&quot;alert(1)&quot;&gt;
40+
</pre>
41+
42+
<p>More exciting XSS vectors can be found on
43+
<a href="http://heideri.ch/jso/" rel="external">HTML5 Security Cheatsheet</a></p>
44+
</div>
45+
</div>
46+
</div>
47+
48+
<footer class="footer">
49+
<div class="container">
50+
<a href="/app/assets/index.html">Back to main</a>
51+
</div>
52+
</footer>
53+
</body>
54+
</html>

src/main/resources/JsXss.ftl.html

+64
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
<html>
2+
<head>
3+
<meta charset="utf-8"/>
4+
<title>TagEscapeResource</title>
5+
<meta content="width=device-width, initial-scale=1, shrink-to-fit=no" name="viewport">
6+
<link href="/app/assets/node_modules/bootstrap/dist/css/bootstrap.min.css" rel="stylesheet">
7+
</head>
8+
<body>
9+
10+
<main class="container" role="main">
11+
<h1>JavaScript variable XSS</h1>
12+
13+
<p>This views is vulnerable to a XSS by injection into a JavaScript variable.</p>
14+
15+
<div id="output">
16+
This is where input text goes when XSS does not work
17+
</div>
18+
19+
<p>
20+
Input=<code>${content}</code>
21+
</p>
22+
23+
<form>
24+
<div class="form-group">
25+
<!-- this sink does not disable auto-escaping and should be safe -->
26+
<input class="form-control" name=input placeholder="%22><script>alert(1)</script>" value="${content}">
27+
</div>
28+
<input class="btn btn-primary" type="submit">
29+
</form>
30+
</main>
31+
32+
<div class="container">
33+
<div class="row">
34+
<div class="col">
35+
<h2>Sample XSS vectors</h2>
36+
37+
<p>We are injecting directly into JavaScript so simple <code>alert(1)</code> will work
38+
once we escape the JavaScript variable context.</p>
39+
40+
<pre>
41+
a"; alert(1);"
42+
</pre>
43+
44+
<p>More exciting XSS vectors can be found on
45+
<a href="http://heideri.ch/jso/" rel="external">HTML5 Security Cheatsheet</a></p>
46+
</div>
47+
</div>
48+
</div>
49+
50+
<!-- this sink has Freemarker auto-escaping explicitly disabled and should cause an XSS -->
51+
<script>
52+
// Trivial JavaScript to insert input into a div contents
53+
var test = "${content?no_esc}";
54+
document.getElementById("output").innerText = test;
55+
56+
</script>
57+
58+
<footer class="footer">
59+
<div class="container">
60+
<a href="/app/assets/index.html">Back to main</a>
61+
</div>
62+
</footer>
63+
</body>
64+
</html>

src/main/resources/TagXss.ftl.html

+1-1
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ <h1>HTML tag XSS</h1>
2424
</form>
2525
</main>
2626

27-
<div class="container-fluid">
27+
<div class="container">
2828
<div class="row">
2929
<div class="col">
3030
<h2>Sample XSS vectors</h2>

0 commit comments

Comments
 (0)