mirror of
https://github.com/github/codeql.git
synced 2026-04-29 18:55:14 +02:00
Merge pull request #4762 from asgerf/js/template-sinks-in-code-injection
Approved by erik-krogh, mchammer01
This commit is contained in:
@@ -30,6 +30,21 @@ for example, steal cookies containing session information.
|
||||
</p>
|
||||
|
||||
<sample src="examples/CodeInjection.js" />
|
||||
|
||||
<p>
|
||||
The following example shows a Pug template being constructed from user input, allowing attackers to run
|
||||
arbitrary code via a payload such as <code>#{global.process.exit(1)}</code>.
|
||||
</p>
|
||||
|
||||
<sample src="examples/ServerSideTemplateInjection.js" />
|
||||
|
||||
<p>
|
||||
Below is an example of how to use a template engine without any risk of template injection.
|
||||
The user input is included via an interpolation expression <code>#{username}</code> whose value is provided
|
||||
as an option to the template, instead of being part of the template string itself:
|
||||
</p>
|
||||
|
||||
<sample src="examples/ServerSideTemplateInjectionSafe.js" />
|
||||
</example>
|
||||
|
||||
<references>
|
||||
@@ -40,5 +55,9 @@ OWASP:
|
||||
<li>
|
||||
Wikipedia: <a href="https://en.wikipedia.org/wiki/Code_injection">Code Injection</a>.
|
||||
</li>
|
||||
<li>
|
||||
PortSwigger Research Blog:
|
||||
<a href="https://portswigger.net/research/server-side-template-injection">Server-Side Template Injection</a>.
|
||||
</li>
|
||||
</references>
|
||||
</qhelp>
|
||||
|
||||
@@ -18,5 +18,6 @@ import DataFlow::PathGraph
|
||||
|
||||
from Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink
|
||||
where cfg.hasFlowPath(source, sink)
|
||||
select sink.getNode(), source, sink, "$@ flows to here and is interpreted as code.",
|
||||
source.getNode(), "User-provided value"
|
||||
select sink.getNode(), source, sink,
|
||||
"$@ flows to " + sink.getNode().(Sink).getMessageSuffix() + ".", source.getNode(),
|
||||
"User-provided value"
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
const express = require('express')
|
||||
var pug = require('pug');
|
||||
const app = express()
|
||||
|
||||
app.post('/', (req, res) => {
|
||||
var input = req.query.username;
|
||||
var template = `
|
||||
doctype
|
||||
html
|
||||
head
|
||||
title= 'Hello world'
|
||||
body
|
||||
form(action='/' method='post')
|
||||
input#name.form-control(type='text)
|
||||
button.btn.btn-primary(type='submit') Submit
|
||||
p Hello `+ input
|
||||
var fn = pug.compile(template);
|
||||
var html = fn();
|
||||
res.send(html);
|
||||
})
|
||||
@@ -0,0 +1,20 @@
|
||||
const express = require('express')
|
||||
var pug = require('pug');
|
||||
const app = express()
|
||||
|
||||
app.post('/', (req, res) => {
|
||||
var input = req.query.username;
|
||||
var template = `
|
||||
doctype
|
||||
html
|
||||
head
|
||||
title= 'Hello world'
|
||||
body
|
||||
form(action='/' method='post')
|
||||
input#name.form-control(type='text)
|
||||
button.btn.btn-primary(type='submit') Submit
|
||||
p Hello #{username}`
|
||||
var fn = pug.compile(template);
|
||||
var html = fn({username: input});
|
||||
res.send(html);
|
||||
})
|
||||
@@ -1,56 +0,0 @@
|
||||
<!DOCTYPE qhelp PUBLIC
|
||||
"-//Semmle//qhelp//EN"
|
||||
"qhelp.dtd">
|
||||
<qhelp>
|
||||
|
||||
<overview>
|
||||
<p>
|
||||
Server-Side Template Injection vulnerabilities occur when user input is embedded
|
||||
in a template in an unsafe manner allowing attackers to access the template context and
|
||||
run arbitrary code on the application server.
|
||||
</p>
|
||||
</overview>
|
||||
|
||||
<recommendation>
|
||||
<p>
|
||||
Avoid including user input in any expression or template which may be dynamically rendered.
|
||||
If user input must be included, use context-specific escaping before including it or run
|
||||
the rendering engine with sandbox options.
|
||||
</p>
|
||||
</recommendation>
|
||||
|
||||
<example>
|
||||
<p>
|
||||
The following example shows a page being rendered with user input allowing attackers to access the
|
||||
template context and run arbitrary code on the application server.
|
||||
The Pug template engine (and other template engines) provides an interpolation feature - insertion of variable values into a string of some kind.
|
||||
For example, <code>Hello #{user.username}!</code>, could be used for printing a username from a scoped variable user,
|
||||
but the <code>user.username</code> expression will be executed as JavaScript.
|
||||
Unsafe injection of user input in a template therefore allows an attacker to inject arbitrary JavaScript code.
|
||||
For example, a payload of <code>#{global.process.exit(1)}</code> will cause the below server to crash.
|
||||
</p>
|
||||
|
||||
<sample src="examples/ServerSideTemplateInjection.js" />
|
||||
</example>
|
||||
|
||||
<example>
|
||||
<p>
|
||||
The example below provides an example of how to use a template engine without any risk of Server-Side Template Injection.
|
||||
Instead of concatenating user input onto the template, the template uses a placeholder and safely inserts
|
||||
the user input.
|
||||
</p>
|
||||
|
||||
<sample src="examples/ServerSideTemplateInjectionSafe.js" />
|
||||
</example>
|
||||
|
||||
<references>
|
||||
<li>
|
||||
OWASP:
|
||||
<a href="https://owasp.org/www-project-web-security-testing-guide/latest/4-Web_Application_Security_Testing/07-Input_Validation_Testing/18-Testing_for_Server_Side_Template_Injection">Server Side Template Injection</a>.
|
||||
</li>
|
||||
<li>
|
||||
PortSwigger Research Blog:
|
||||
<a href="https://portswigger.net/research/server-side-template-injection">Server-Side Template Injection</a>.
|
||||
</li>
|
||||
</references>
|
||||
</qhelp>
|
||||
@@ -1,68 +0,0 @@
|
||||
/**
|
||||
* @name Server Side Template Injection
|
||||
* @description Rendering templates with unsanitized user input allows a malicious user arbitrary
|
||||
* code execution.
|
||||
* @kind path-problem
|
||||
* @problem.severity error
|
||||
* @precision high
|
||||
* @id js/server-side-template-injection
|
||||
* @tags security
|
||||
* external/cwe/cwe-094
|
||||
*/
|
||||
|
||||
import javascript
|
||||
import DataFlow
|
||||
import DataFlow::PathGraph
|
||||
|
||||
class ServerSideTemplateInjectionConfiguration extends TaintTracking::Configuration {
|
||||
ServerSideTemplateInjectionConfiguration() { this = "ServerSideTemplateInjectionConfiguration" }
|
||||
|
||||
override predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource }
|
||||
|
||||
override predicate isSink(DataFlow::Node sink) { sink instanceof ServerSideTemplateInjectionSink }
|
||||
}
|
||||
|
||||
abstract class ServerSideTemplateInjectionSink extends DataFlow::Node { }
|
||||
|
||||
class SSTIPugSink extends ServerSideTemplateInjectionSink {
|
||||
SSTIPugSink() {
|
||||
exists(CallNode compile, ModuleImportNode renderImport |
|
||||
renderImport = moduleImport(["pug", "jade"]) and
|
||||
(
|
||||
compile = renderImport.getAMemberCall("compile")
|
||||
or
|
||||
compile = renderImport.getAMemberCall("render")
|
||||
) and
|
||||
this = compile.getArgument(0)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
class SSTIDotSink extends ServerSideTemplateInjectionSink {
|
||||
SSTIDotSink() {
|
||||
exists(CallNode compile |
|
||||
compile = moduleImport("dot").getAMemberCall("template") and
|
||||
this = compile.getArgument(0)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
class SSTIEjsSink extends ServerSideTemplateInjectionSink {
|
||||
SSTIEjsSink() { this = moduleImport("ejs").getAMemberCall("render").getArgument(0) }
|
||||
}
|
||||
|
||||
class SSTINunjucksSink extends ServerSideTemplateInjectionSink {
|
||||
SSTINunjucksSink() {
|
||||
this = moduleImport("nunjucks").getAMemberCall("renderString").getArgument(0)
|
||||
}
|
||||
}
|
||||
|
||||
class LodashTemplateSink extends ServerSideTemplateInjectionSink {
|
||||
LodashTemplateSink() { this = LodashUnderscore::member("template").getACall().getArgument(0) }
|
||||
}
|
||||
|
||||
from DataFlow::PathNode source, DataFlow::PathNode sink, ServerSideTemplateInjectionConfiguration c
|
||||
where c.hasFlowPath(source, sink)
|
||||
select sink.getNode(), source, sink,
|
||||
"$@ flows to here and unsafely used as part of rendered template", source.getNode(),
|
||||
"User-provided value"
|
||||
@@ -1,35 +0,0 @@
|
||||
const express = require('express')
|
||||
var bodyParser = require('body-parser');
|
||||
const app = express()
|
||||
app.use(bodyParser.json());
|
||||
app.use(bodyParser.urlencoded({ extended: true }));
|
||||
|
||||
//Dependent of Templating engine
|
||||
var jade = require('pug');
|
||||
const port = 5061
|
||||
|
||||
function getHTML(input) {
|
||||
var template = `
|
||||
doctype
|
||||
html
|
||||
head
|
||||
title= 'Hello world'
|
||||
body
|
||||
form(action='/' method='post')
|
||||
label(for='name') Name:
|
||||
input#name.form-control(type='text', placeholder='' name='name')
|
||||
button.btn.btn-primary(type='submit') Submit
|
||||
p Hello `+ input
|
||||
var fn = jade.compile(template);
|
||||
var html = fn();
|
||||
console.log(html);
|
||||
return html;
|
||||
}
|
||||
|
||||
app.post('/', (request, response) => {
|
||||
var input = request.param('name', "")
|
||||
var html = getHTML(input)
|
||||
response.send(html);
|
||||
})
|
||||
|
||||
app.listen(port, () => { console.log(`server is listening on ${port}`) })
|
||||
@@ -1,34 +0,0 @@
|
||||
const express = require('express')
|
||||
var bodyParser = require('body-parser');
|
||||
const app = express()
|
||||
app.use(bodyParser.urlencoded({ extended: true }));
|
||||
|
||||
//Dependent of Templating engine
|
||||
var jade = require('pug');
|
||||
const port = 5061
|
||||
|
||||
function getHTML(input) {
|
||||
var template = `
|
||||
doctype
|
||||
html
|
||||
head
|
||||
title= 'Hello world'
|
||||
body
|
||||
form(action='/' method='post')
|
||||
label(for='name') Name:
|
||||
input#name.form-control(type='text', placeholder='' name='name')
|
||||
button.btn.btn-primary(type='submit') Submit
|
||||
p Hello #{username}`
|
||||
var fn = jade.compile(template);
|
||||
var html = fn({username: input});
|
||||
console.log(html);
|
||||
return html;
|
||||
}
|
||||
|
||||
app.post('/', (request, response) => {
|
||||
var input = request.param('name', "")
|
||||
var html = getHTML(input)
|
||||
response.send(html);
|
||||
})
|
||||
|
||||
app.listen(port, () => { console.log(`server is listening on ${port}`) })
|
||||
@@ -15,7 +15,12 @@ module CodeInjection {
|
||||
/**
|
||||
* A data flow sink for code injection vulnerabilities.
|
||||
*/
|
||||
abstract class Sink extends DataFlow::Node { }
|
||||
abstract class Sink extends DataFlow::Node {
|
||||
/**
|
||||
* Gets the substitute for `X` in the message `User-provided value flows to X`.
|
||||
*/
|
||||
string getMessageSuffix() { result = "here and is interpreted as code" }
|
||||
}
|
||||
|
||||
/**
|
||||
* A sanitizer for code injection vulnerabilities.
|
||||
@@ -138,4 +143,57 @@ module CodeInjection {
|
||||
API::moduleImport("module").getInstance().getMember("_compile").getACall().getArgument(0)
|
||||
}
|
||||
}
|
||||
|
||||
/** A sink for code injection via template injection. */
|
||||
abstract private class TemplateSink extends Sink {
|
||||
override string getMessageSuffix() {
|
||||
result = "here and is interpreted as a template, which may contain code"
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A value interpreted as as template by the `pug` library.
|
||||
*/
|
||||
class PugTemplateSink extends TemplateSink {
|
||||
PugTemplateSink() {
|
||||
this =
|
||||
DataFlow::moduleImport(["pug", "jade"]).getAMemberCall(["compile", "render"]).getArgument(0)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A value interpreted as a tempalte by the `dot` library.
|
||||
*/
|
||||
class DotTemplateSink extends TemplateSink {
|
||||
DotTemplateSink() {
|
||||
this = DataFlow::moduleImport("dot").getAMemberCall("template").getArgument(0)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A value interpreted as a template by the `ejs` library.
|
||||
*/
|
||||
class EjsTemplateSink extends TemplateSink {
|
||||
EjsTemplateSink() {
|
||||
this = DataFlow::moduleImport("ejs").getAMemberCall("render").getArgument(0)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A value interpreted as a template by the `nunjucks` library.
|
||||
*/
|
||||
class NunjucksTemplateSink extends TemplateSink {
|
||||
NunjucksTemplateSink() {
|
||||
this = DataFlow::moduleImport("nunjucks").getAMemberCall("renderString").getArgument(0)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A value interpreted as a template by `lodash` or `underscore`.
|
||||
*/
|
||||
class LodashUnderscoreTemplateSink extends TemplateSink {
|
||||
LodashUnderscoreTemplateSink() {
|
||||
this = LodashUnderscore::member("template").getACall().getArgument(0)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -118,6 +118,25 @@ nodes
|
||||
| react-native.js:8:32:8:38 | tainted |
|
||||
| react-native.js:10:23:10:29 | tainted |
|
||||
| react-native.js:10:23:10:29 | tainted |
|
||||
| template-sinks.js:12:9:12:31 | tainted |
|
||||
| template-sinks.js:12:19:12:31 | req.query.foo |
|
||||
| template-sinks.js:12:19:12:31 | req.query.foo |
|
||||
| template-sinks.js:14:17:14:23 | tainted |
|
||||
| template-sinks.js:14:17:14:23 | tainted |
|
||||
| template-sinks.js:15:16:15:22 | tainted |
|
||||
| template-sinks.js:15:16:15:22 | tainted |
|
||||
| template-sinks.js:16:18:16:24 | tainted |
|
||||
| template-sinks.js:16:18:16:24 | tainted |
|
||||
| template-sinks.js:17:17:17:23 | tainted |
|
||||
| template-sinks.js:17:17:17:23 | tainted |
|
||||
| template-sinks.js:18:18:18:24 | tainted |
|
||||
| template-sinks.js:18:18:18:24 | tainted |
|
||||
| template-sinks.js:19:16:19:22 | tainted |
|
||||
| template-sinks.js:19:16:19:22 | tainted |
|
||||
| template-sinks.js:20:27:20:33 | tainted |
|
||||
| template-sinks.js:20:27:20:33 | tainted |
|
||||
| template-sinks.js:21:21:21:27 | tainted |
|
||||
| template-sinks.js:21:21:21:27 | tainted |
|
||||
| tst.js:2:6:2:22 | document.location |
|
||||
| tst.js:2:6:2:22 | document.location |
|
||||
| tst.js:2:6:2:27 | documen ... on.href |
|
||||
@@ -256,6 +275,24 @@ edges
|
||||
| react-native.js:7:7:7:33 | tainted | react-native.js:10:23:10:29 | tainted |
|
||||
| react-native.js:7:17:7:33 | req.param("code") | react-native.js:7:7:7:33 | tainted |
|
||||
| react-native.js:7:17:7:33 | req.param("code") | react-native.js:7:7:7:33 | tainted |
|
||||
| template-sinks.js:12:9:12:31 | tainted | template-sinks.js:14:17:14:23 | tainted |
|
||||
| template-sinks.js:12:9:12:31 | tainted | template-sinks.js:14:17:14:23 | tainted |
|
||||
| template-sinks.js:12:9:12:31 | tainted | template-sinks.js:15:16:15:22 | tainted |
|
||||
| template-sinks.js:12:9:12:31 | tainted | template-sinks.js:15:16:15:22 | tainted |
|
||||
| template-sinks.js:12:9:12:31 | tainted | template-sinks.js:16:18:16:24 | tainted |
|
||||
| template-sinks.js:12:9:12:31 | tainted | template-sinks.js:16:18:16:24 | tainted |
|
||||
| template-sinks.js:12:9:12:31 | tainted | template-sinks.js:17:17:17:23 | tainted |
|
||||
| template-sinks.js:12:9:12:31 | tainted | template-sinks.js:17:17:17:23 | tainted |
|
||||
| template-sinks.js:12:9:12:31 | tainted | template-sinks.js:18:18:18:24 | tainted |
|
||||
| template-sinks.js:12:9:12:31 | tainted | template-sinks.js:18:18:18:24 | tainted |
|
||||
| template-sinks.js:12:9:12:31 | tainted | template-sinks.js:19:16:19:22 | tainted |
|
||||
| template-sinks.js:12:9:12:31 | tainted | template-sinks.js:19:16:19:22 | tainted |
|
||||
| template-sinks.js:12:9:12:31 | tainted | template-sinks.js:20:27:20:33 | tainted |
|
||||
| template-sinks.js:12:9:12:31 | tainted | template-sinks.js:20:27:20:33 | tainted |
|
||||
| template-sinks.js:12:9:12:31 | tainted | template-sinks.js:21:21:21:27 | tainted |
|
||||
| template-sinks.js:12:9:12:31 | tainted | template-sinks.js:21:21:21:27 | tainted |
|
||||
| template-sinks.js:12:19:12:31 | req.query.foo | template-sinks.js:12:9:12:31 | tainted |
|
||||
| template-sinks.js:12:19:12:31 | req.query.foo | template-sinks.js:12:9:12:31 | tainted |
|
||||
| tst.js:2:6:2:22 | document.location | tst.js:2:6:2:27 | documen ... on.href |
|
||||
| tst.js:2:6:2:22 | document.location | tst.js:2:6:2:27 | documen ... on.href |
|
||||
| tst.js:2:6:2:27 | documen ... on.href | tst.js:2:6:2:83 | documen ... t=")+8) |
|
||||
@@ -315,6 +352,14 @@ edges
|
||||
| module.js:9:16:9:29 | req.query.code | module.js:9:16:9:29 | req.query.code | module.js:9:16:9:29 | req.query.code | $@ flows to here and is interpreted as code. | module.js:9:16:9:29 | req.query.code | User-provided value |
|
||||
| react-native.js:8:32:8:38 | tainted | react-native.js:7:17:7:33 | req.param("code") | react-native.js:8:32:8:38 | tainted | $@ flows to here and is interpreted as code. | react-native.js:7:17:7:33 | req.param("code") | User-provided value |
|
||||
| react-native.js:10:23:10:29 | tainted | react-native.js:7:17:7:33 | req.param("code") | react-native.js:10:23:10:29 | tainted | $@ flows to here and is interpreted as code. | react-native.js:7:17:7:33 | req.param("code") | User-provided value |
|
||||
| template-sinks.js:14:17:14:23 | tainted | template-sinks.js:12:19:12:31 | req.query.foo | template-sinks.js:14:17:14:23 | tainted | $@ flows to here and is interpreted as a template, which may contain code. | template-sinks.js:12:19:12:31 | req.query.foo | User-provided value |
|
||||
| template-sinks.js:15:16:15:22 | tainted | template-sinks.js:12:19:12:31 | req.query.foo | template-sinks.js:15:16:15:22 | tainted | $@ flows to here and is interpreted as a template, which may contain code. | template-sinks.js:12:19:12:31 | req.query.foo | User-provided value |
|
||||
| template-sinks.js:16:18:16:24 | tainted | template-sinks.js:12:19:12:31 | req.query.foo | template-sinks.js:16:18:16:24 | tainted | $@ flows to here and is interpreted as a template, which may contain code. | template-sinks.js:12:19:12:31 | req.query.foo | User-provided value |
|
||||
| template-sinks.js:17:17:17:23 | tainted | template-sinks.js:12:19:12:31 | req.query.foo | template-sinks.js:17:17:17:23 | tainted | $@ flows to here and is interpreted as a template, which may contain code. | template-sinks.js:12:19:12:31 | req.query.foo | User-provided value |
|
||||
| template-sinks.js:18:18:18:24 | tainted | template-sinks.js:12:19:12:31 | req.query.foo | template-sinks.js:18:18:18:24 | tainted | $@ flows to here and is interpreted as a template, which may contain code. | template-sinks.js:12:19:12:31 | req.query.foo | User-provided value |
|
||||
| template-sinks.js:19:16:19:22 | tainted | template-sinks.js:12:19:12:31 | req.query.foo | template-sinks.js:19:16:19:22 | tainted | $@ flows to here and is interpreted as a template, which may contain code. | template-sinks.js:12:19:12:31 | req.query.foo | User-provided value |
|
||||
| template-sinks.js:20:27:20:33 | tainted | template-sinks.js:12:19:12:31 | req.query.foo | template-sinks.js:20:27:20:33 | tainted | $@ flows to here and is interpreted as a template, which may contain code. | template-sinks.js:12:19:12:31 | req.query.foo | User-provided value |
|
||||
| template-sinks.js:21:21:21:27 | tainted | template-sinks.js:12:19:12:31 | req.query.foo | template-sinks.js:21:21:21:27 | tainted | $@ flows to here and is interpreted as a template, which may contain code. | template-sinks.js:12:19:12:31 | req.query.foo | User-provided value |
|
||||
| tst.js:2:6:2:83 | documen ... t=")+8) | tst.js:2:6:2:22 | document.location | tst.js:2:6:2:83 | documen ... t=")+8) | $@ flows to here and is interpreted as code. | tst.js:2:6:2:22 | document.location | User-provided value |
|
||||
| tst.js:5:12:5:33 | documen ... on.hash | tst.js:5:12:5:28 | document.location | tst.js:5:12:5:33 | documen ... on.hash | $@ flows to here and is interpreted as code. | tst.js:5:12:5:28 | document.location | User-provided value |
|
||||
| tst.js:14:10:14:74 | documen ... , "$1") | tst.js:14:10:14:26 | document.location | tst.js:14:10:14:74 | documen ... , "$1") | $@ flows to here and is interpreted as code. | tst.js:14:10:14:26 | document.location | User-provided value |
|
||||
|
||||
@@ -122,6 +122,25 @@ nodes
|
||||
| react-native.js:8:32:8:38 | tainted |
|
||||
| react-native.js:10:23:10:29 | tainted |
|
||||
| react-native.js:10:23:10:29 | tainted |
|
||||
| template-sinks.js:12:9:12:31 | tainted |
|
||||
| template-sinks.js:12:19:12:31 | req.query.foo |
|
||||
| template-sinks.js:12:19:12:31 | req.query.foo |
|
||||
| template-sinks.js:14:17:14:23 | tainted |
|
||||
| template-sinks.js:14:17:14:23 | tainted |
|
||||
| template-sinks.js:15:16:15:22 | tainted |
|
||||
| template-sinks.js:15:16:15:22 | tainted |
|
||||
| template-sinks.js:16:18:16:24 | tainted |
|
||||
| template-sinks.js:16:18:16:24 | tainted |
|
||||
| template-sinks.js:17:17:17:23 | tainted |
|
||||
| template-sinks.js:17:17:17:23 | tainted |
|
||||
| template-sinks.js:18:18:18:24 | tainted |
|
||||
| template-sinks.js:18:18:18:24 | tainted |
|
||||
| template-sinks.js:19:16:19:22 | tainted |
|
||||
| template-sinks.js:19:16:19:22 | tainted |
|
||||
| template-sinks.js:20:27:20:33 | tainted |
|
||||
| template-sinks.js:20:27:20:33 | tainted |
|
||||
| template-sinks.js:21:21:21:27 | tainted |
|
||||
| template-sinks.js:21:21:21:27 | tainted |
|
||||
| tst.js:2:6:2:22 | document.location |
|
||||
| tst.js:2:6:2:22 | document.location |
|
||||
| tst.js:2:6:2:27 | documen ... on.href |
|
||||
@@ -264,6 +283,24 @@ edges
|
||||
| react-native.js:7:7:7:33 | tainted | react-native.js:10:23:10:29 | tainted |
|
||||
| react-native.js:7:17:7:33 | req.param("code") | react-native.js:7:7:7:33 | tainted |
|
||||
| react-native.js:7:17:7:33 | req.param("code") | react-native.js:7:7:7:33 | tainted |
|
||||
| template-sinks.js:12:9:12:31 | tainted | template-sinks.js:14:17:14:23 | tainted |
|
||||
| template-sinks.js:12:9:12:31 | tainted | template-sinks.js:14:17:14:23 | tainted |
|
||||
| template-sinks.js:12:9:12:31 | tainted | template-sinks.js:15:16:15:22 | tainted |
|
||||
| template-sinks.js:12:9:12:31 | tainted | template-sinks.js:15:16:15:22 | tainted |
|
||||
| template-sinks.js:12:9:12:31 | tainted | template-sinks.js:16:18:16:24 | tainted |
|
||||
| template-sinks.js:12:9:12:31 | tainted | template-sinks.js:16:18:16:24 | tainted |
|
||||
| template-sinks.js:12:9:12:31 | tainted | template-sinks.js:17:17:17:23 | tainted |
|
||||
| template-sinks.js:12:9:12:31 | tainted | template-sinks.js:17:17:17:23 | tainted |
|
||||
| template-sinks.js:12:9:12:31 | tainted | template-sinks.js:18:18:18:24 | tainted |
|
||||
| template-sinks.js:12:9:12:31 | tainted | template-sinks.js:18:18:18:24 | tainted |
|
||||
| template-sinks.js:12:9:12:31 | tainted | template-sinks.js:19:16:19:22 | tainted |
|
||||
| template-sinks.js:12:9:12:31 | tainted | template-sinks.js:19:16:19:22 | tainted |
|
||||
| template-sinks.js:12:9:12:31 | tainted | template-sinks.js:20:27:20:33 | tainted |
|
||||
| template-sinks.js:12:9:12:31 | tainted | template-sinks.js:20:27:20:33 | tainted |
|
||||
| template-sinks.js:12:9:12:31 | tainted | template-sinks.js:21:21:21:27 | tainted |
|
||||
| template-sinks.js:12:9:12:31 | tainted | template-sinks.js:21:21:21:27 | tainted |
|
||||
| template-sinks.js:12:19:12:31 | req.query.foo | template-sinks.js:12:9:12:31 | tainted |
|
||||
| template-sinks.js:12:19:12:31 | req.query.foo | template-sinks.js:12:9:12:31 | tainted |
|
||||
| tst.js:2:6:2:22 | document.location | tst.js:2:6:2:27 | documen ... on.href |
|
||||
| tst.js:2:6:2:22 | document.location | tst.js:2:6:2:27 | documen ... on.href |
|
||||
| tst.js:2:6:2:27 | documen ... on.href | tst.js:2:6:2:83 | documen ... t=")+8) |
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
import express from 'express';
|
||||
import * as pug from 'pug';
|
||||
import * as jade from 'jade';
|
||||
import * as dot from 'dot';
|
||||
import * as ejs from 'ejs';
|
||||
import * as nunjucks from 'nunjucks';
|
||||
import * as lodash from 'lodash';
|
||||
|
||||
var app = express();
|
||||
|
||||
app.get('/some/path', function(req, res) {
|
||||
let tainted = req.query.foo;
|
||||
|
||||
pug.compile(tainted); // NOT OK
|
||||
pug.render(tainted); // NOT OK
|
||||
jade.compile(tainted); // NOT OK
|
||||
jade.render(tainted); // NOT OK
|
||||
dot.template(tainted); // NOT OK
|
||||
ejs.render(tainted); // NOT OK
|
||||
nunjucks.renderString(tainted); // NOT OK
|
||||
lodash.template(tainted); // NOT OK
|
||||
});
|
||||
Reference in New Issue
Block a user