Skip to content
This repository was archived by the owner on Mar 3, 2026. It is now read-only.

Commit a30b327

Browse files
committed
xss on template engines fix jooby-project#476
1 parent 875e718 commit a30b327

File tree

27 files changed

+404
-47
lines changed

27 files changed

+404
-47
lines changed
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
package org.jooby.ftl;
2+
3+
import org.jooby.Results;
4+
import org.jooby.test.ServerFeature;
5+
import org.jooby.xss.XSS;
6+
import org.junit.Test;
7+
8+
public class Issue476FtlXss extends ServerFeature {
9+
10+
{
11+
use(new XSS());
12+
13+
use(new Ftl());
14+
15+
get("/", req -> Results.html("org/jooby/ftl/xss").put("input", "<script>alert('xss');</script>"));
16+
}
17+
18+
@Test
19+
public void xssFn() throws Exception {
20+
request()
21+
.get("/")
22+
.expect("<!DOCTYPE html>\n" +
23+
"<html>\n" +
24+
" <body><a href=\"javascript:hello('&#x5C;u003Cscript&#x5C;u003Ealert%28&#x5C;u0027xss&#x5C;u0027%29%3B&#x5C;u003C&#x5C;u002Fscript&#x5C;u003E')\"></a>\n" +
25+
" </body>\n" +
26+
"</html>");
27+
}
28+
29+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
package org.jooby.hbs;
2+
3+
import org.jooby.Results;
4+
import org.jooby.test.ServerFeature;
5+
import org.jooby.xss.XSS;
6+
import org.junit.Test;
7+
8+
public class Issue476HbsXss extends ServerFeature {
9+
10+
{
11+
use(new XSS());
12+
13+
use(new Hbs());
14+
15+
get("/",
16+
req -> Results.html("org/jooby/hbs/xss").put("input", "<script>alert('xss');</script>"));
17+
}
18+
19+
@Test
20+
public void xssFn() throws Exception {
21+
request()
22+
.get("/")
23+
.expect("<!DOCTYPE html>\n" +
24+
"<html>\n" +
25+
" <body><a href=\"javascript:hello('&#x5C;u003Cscript&#x5C;u003Ealert%28&#x5C;u0027xss&#x5C;u0027%29%3B&#x5C;u003C&#x5C;u002Fscript&#x5C;u003E')\"></a>\n"
26+
+
27+
" </body>\n" +
28+
"</html>");
29+
}
30+
31+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
package org.jooby.jade;
2+
3+
import org.jooby.Results;
4+
import org.jooby.test.ServerFeature;
5+
import org.jooby.xss.XSS;
6+
import org.junit.Test;
7+
8+
public class Issue476JadeXss extends ServerFeature {
9+
10+
{
11+
use(new XSS());
12+
13+
use(new Jade(".html"));
14+
15+
get("/",
16+
req -> Results.html("org/jooby/jade/xss").put("input", "<script>alert('xss');</script>"));
17+
}
18+
19+
@Test
20+
public void xssFn() throws Exception {
21+
request()
22+
.get("/")
23+
.expect("<!DOCTYPE html>\n" +
24+
"<html>\n" +
25+
" <body><a href=\"javascript:hello('&amp;#x5C;u003Cscript&amp;#x5C;u003Ealert%28&amp;#x5C;u0027xss&amp;#x5C;u0027%29%3B&amp;#x5C;u003C&amp;#x5C;u002Fscript&amp;#x5C;u003E')\"></a></body>\n" +
26+
"</html>");
27+
}
28+
29+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
package org.jooby.pebble;
2+
3+
import org.jooby.Results;
4+
import org.jooby.test.ServerFeature;
5+
import org.jooby.xss.XSS;
6+
import org.junit.Test;
7+
8+
public class Issue476PebbleXss extends ServerFeature {
9+
10+
{
11+
use(new XSS());
12+
13+
use(new Pebble());
14+
15+
get("/", req -> Results.html("org/jooby/pebble/xss").put("input", "<script>alert('xss');</script>"));
16+
}
17+
18+
@Test
19+
public void xssFn() throws Exception {
20+
request()
21+
.get("/")
22+
.expect("<!DOCTYPE html>\n" +
23+
"<html>\n" +
24+
" <body><a href=\"javascript:hello('&amp;#x5C;u003Cscript&amp;#x5C;u003Ealert%28&amp;#x5C;u0027xss&amp;#x5C;u0027%29%3B&amp;#x5C;u003C&amp;#x5C;u002Fscript&amp;#x5C;u003E')\"></a>\n" +
25+
" </body>\n" +
26+
"</html>");
27+
}
28+
29+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<body><a href="javascript:hello('${xss(input, "js", "uri", "html")}')"></a>
4+
</body>
5+
</html>
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<body><a href="javascript:hello('{{xss input 'js' 'uri' 'html'}}')"></a>
4+
</body>
5+
</html>
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
doctype html
2+
html
3+
body
4+
a(href= "javascript:hello('" + xss.apply(input, "js", "uri", "html") + "')")
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<body><a href="javascript:hello('{{xss (input, 'js', 'uri', 'html')}}')"></a>
4+
</body>
5+
</html>

jooby-csl/src/main/java/org/jooby/xss/XSS.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@
5757
* If you want to learn more about nested context and why they are important have a look at this
5858
* <a href=
5959
* "http://security.coverity.com/document/2013/Mar/fixing-xss-a-practical-guide-for-developers.html">nice
60-
* guide</code> from
60+
* guide</a> from
6161
* <a href="https://github.com/coverity/coverity-security-library">coverity-security-library</a>.
6262
* </p>
6363
*

jooby-ftl/src/main/java/org/jooby/ftl/Ftl.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
import org.jooby.Renderer;
2929
import org.jooby.internal.ftl.Engine;
3030
import org.jooby.internal.ftl.GuavaCacheStorage;
31+
import org.jooby.internal.ftl.XssDirective;
3132
import org.slf4j.Logger;
3233
import org.slf4j.LoggerFactory;
3334

@@ -194,7 +195,7 @@ public void configure(final Env env, final Config config, final Binder binder) {
194195

195196
binder.bind(Configuration.class).toInstance(freemarker);
196197

197-
Engine engine = new Engine(freemarker, suffix);
198+
Engine engine = new Engine(freemarker, suffix, new XssDirective(env));
198199

199200
Multibinder.newSetBinder(binder, Renderer.class)
200201
.addBinding().toInstance(engine);

0 commit comments

Comments
 (0)