mirror of
https://github.com/github/codeql.git
synced 2026-04-25 08:45:14 +02:00
Merge pull request #13624 from jorgectf/seclab/dotjs
JS: Add `dot.js` support
This commit is contained in:
@@ -153,7 +153,7 @@ import com.semmle.util.trap.TrapWriter;
|
||||
* <li>All JavaScript files, that is, files with one of the extensions supported by {@link
|
||||
* FileType#JS} (currently ".js", ".jsx", ".mjs", ".cjs", ".es6", ".es").
|
||||
* <li>All HTML files, that is, files with with one of the extensions supported by {@link
|
||||
* FileType#HTML} (currently ".htm", ".html", ".xhtm", ".xhtml", ".vue", ".html.erb", ".jsp").
|
||||
* FileType#HTML} (currently ".htm", ".html", ".xhtm", ".xhtml", ".vue", ".html.erb", ".html.dot", ".jsp").
|
||||
* <li>All YAML files, that is, files with one of the extensions supported by {@link
|
||||
* FileType#YAML} (currently ".raml", ".yaml", ".yml").
|
||||
* <li>Files with base name "package.json" or "tsconfig.json", and files whose base name
|
||||
|
||||
@@ -103,7 +103,7 @@ public class FileExtractor {
|
||||
|
||||
/** Information about supported file types. */
|
||||
public static enum FileType {
|
||||
HTML(".htm", ".html", ".xhtm", ".xhtml", ".vue", ".hbs", ".ejs", ".njk", ".erb", ".jsp") {
|
||||
HTML(".htm", ".html", ".xhtm", ".xhtml", ".vue", ".hbs", ".ejs", ".njk", ".erb", ".jsp", ".dot") {
|
||||
@Override
|
||||
public IExtractor mkExtractor(ExtractorConfig config, ExtractorState state) {
|
||||
return new HTMLExtractor(config, state);
|
||||
@@ -125,6 +125,12 @@ public class FileExtractor {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
// for DOT files we are only interrested in `.html.dot` files
|
||||
if (FileUtil.extension(f).equalsIgnoreCase(".dot")) {
|
||||
if (!f.getName().toLowerCase().endsWith(".html.dot")) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return super.contains(f, lcExt, config);
|
||||
}
|
||||
},
|
||||
|
||||
@@ -8,13 +8,13 @@ import com.semmle.util.trap.TrapWriter.Label;
|
||||
|
||||
public class TemplateEngines {
|
||||
private static final String MUSTACHE_TAG_TRIPLE = "\\{\\{\\{[~]?(.*?)[~]?\\}\\}\\}"; // {{{ x }}}
|
||||
private static final String MUSTACHE_TAG_DOUBLE = "\\{\\{(?!\\{)[~&]?(.*?)[~]?\\}\\}"; // {{ x }}}
|
||||
private static final String MUSTACHE_TAG_DOUBLE = "\\{\\{(?!\\{)[~&!=]?(.*?)[~]?\\}\\}"; // {{ x }}}
|
||||
private static final String MUSTACHE_TAG_PERCENT = "\\{%(?!>)(.*?)%\\}"; // {% x %}
|
||||
private static final String EJS_TAG = "<%(?![%<>}])[-=]?(.*?)[_-]?%>"; // <% x %>
|
||||
|
||||
/** Pattern for a template tag whose contents should be parsed as an expression */
|
||||
public static final Pattern TEMPLATE_EXPR_OPENING_TAG =
|
||||
Pattern.compile("^(?:\\{\\{\\{?|<%[-=])"); // {{, {{{, <%=, <%-
|
||||
Pattern.compile("^(?:\\{\\{[{!]?|<%[-=])"); // {{, {{{, {{!, <%=, <%-
|
||||
|
||||
/**
|
||||
* Pattern matching a template tag from a supported template engine.
|
||||
|
||||
@@ -580,6 +580,22 @@ module Templating {
|
||||
override string getAPackageName() { result = "ejs" }
|
||||
}
|
||||
|
||||
/**
|
||||
* doT-style syntax, using `{{! }}` for safe interpolation, and `{{= }}` for
|
||||
* unsafe interpolation.
|
||||
*/
|
||||
private class DotStyleSyntax extends TemplateSyntax {
|
||||
DotStyleSyntax() { this = "dot" }
|
||||
|
||||
override string getRawInterpolationRegexp() { result = "(?s)\\{\\{!(.*?)\\}\\}" }
|
||||
|
||||
override string getEscapingInterpolationRegexp() { result = "(?s)\\{\\{=(.*?)\\}\\}" }
|
||||
|
||||
override string getAFileExtension() { result = "dot" }
|
||||
|
||||
override string getAPackageName() { result = "dot" }
|
||||
}
|
||||
|
||||
private TemplateSyntax getOwnTemplateSyntaxInFolder(Folder f) {
|
||||
exists(PackageDependencies deps |
|
||||
deps.getADependency(result.getAPackageName(), _) and
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* Added support for [doT](https://github.com/olado/doT) templates.
|
||||
@@ -50,6 +50,9 @@ nodes
|
||||
| app.js:66:18:66:34 | req.query.rawHtml |
|
||||
| app.js:66:18:66:34 | req.query.rawHtml |
|
||||
| app.js:66:18:66:34 | req.query.rawHtml |
|
||||
| app.js:73:18:73:30 | req.query.foo |
|
||||
| app.js:73:18:73:30 | req.query.foo |
|
||||
| app.js:73:18:73:30 | req.query.foo |
|
||||
| projectA/src/index.js:6:38:6:53 | req.query.taintA |
|
||||
| projectA/src/index.js:6:38:6:53 | req.query.taintA |
|
||||
| projectA/src/index.js:6:38:6:53 | req.query.taintA |
|
||||
@@ -144,6 +147,11 @@ nodes
|
||||
| views/angularjs_sinks.ejs:4:9:4:22 | <%- rawHtml %> |
|
||||
| views/angularjs_sinks.ejs:4:13:4:19 | rawHtml |
|
||||
| views/angularjs_sinks.ejs:4:13:4:19 | rawHtml |
|
||||
| views/dot_sinks.html.dot:3:9:3:22 | {{! tainted }} |
|
||||
| views/dot_sinks.html.dot:3:9:3:22 | {{! tainted }} |
|
||||
| views/dot_sinks.html.dot:3:9:3:22 | {{! tainted }} |
|
||||
| views/dot_sinks.html.dot:3:13:3:19 | tainted |
|
||||
| views/dot_sinks.html.dot:3:13:3:19 | tainted |
|
||||
| views/ejs_include1.ejs:1:1:1:10 | <%- foo %> |
|
||||
| views/ejs_include1.ejs:1:1:1:10 | <%- foo %> |
|
||||
| views/ejs_include1.ejs:1:1:1:10 | <%- foo %> |
|
||||
@@ -367,6 +375,10 @@ edges
|
||||
| app.js:66:18:66:34 | req.query.rawHtml | views/angularjs_sinks.ejs:4:13:4:19 | rawHtml |
|
||||
| app.js:66:18:66:34 | req.query.rawHtml | views/angularjs_sinks.ejs:4:13:4:19 | rawHtml |
|
||||
| app.js:66:18:66:34 | req.query.rawHtml | views/angularjs_sinks.ejs:4:13:4:19 | rawHtml |
|
||||
| app.js:73:18:73:30 | req.query.foo | views/dot_sinks.html.dot:3:13:3:19 | tainted |
|
||||
| app.js:73:18:73:30 | req.query.foo | views/dot_sinks.html.dot:3:13:3:19 | tainted |
|
||||
| app.js:73:18:73:30 | req.query.foo | views/dot_sinks.html.dot:3:13:3:19 | tainted |
|
||||
| app.js:73:18:73:30 | req.query.foo | views/dot_sinks.html.dot:3:13:3:19 | tainted |
|
||||
| projectA/src/index.js:6:38:6:53 | req.query.taintA | projectA/views/main.ejs:5:5:5:23 | taintedInMiddleware |
|
||||
| projectA/src/index.js:6:38:6:53 | req.query.taintA | projectA/views/main.ejs:5:5:5:23 | taintedInMiddleware |
|
||||
| projectA/src/index.js:6:38:6:53 | req.query.taintA | projectA/views/main.ejs:5:5:5:23 | taintedInMiddleware |
|
||||
@@ -463,6 +475,10 @@ edges
|
||||
| views/angularjs_sinks.ejs:4:13:4:19 | rawHtml | views/angularjs_sinks.ejs:4:9:4:22 | <%- rawHtml %> |
|
||||
| views/angularjs_sinks.ejs:4:13:4:19 | rawHtml | views/angularjs_sinks.ejs:4:9:4:22 | <%- rawHtml %> |
|
||||
| views/angularjs_sinks.ejs:4:13:4:19 | rawHtml | views/angularjs_sinks.ejs:4:9:4:22 | <%- rawHtml %> |
|
||||
| views/dot_sinks.html.dot:3:13:3:19 | tainted | views/dot_sinks.html.dot:3:9:3:22 | {{! tainted }} |
|
||||
| views/dot_sinks.html.dot:3:13:3:19 | tainted | views/dot_sinks.html.dot:3:9:3:22 | {{! tainted }} |
|
||||
| views/dot_sinks.html.dot:3:13:3:19 | tainted | views/dot_sinks.html.dot:3:9:3:22 | {{! tainted }} |
|
||||
| views/dot_sinks.html.dot:3:13:3:19 | tainted | views/dot_sinks.html.dot:3:9:3:22 | {{! tainted }} |
|
||||
| views/ejs_include1.ejs:1:5:1:7 | foo | views/ejs_include1.ejs:1:1:1:10 | <%- foo %> |
|
||||
| views/ejs_include1.ejs:1:5:1:7 | foo | views/ejs_include1.ejs:1:1:1:10 | <%- foo %> |
|
||||
| views/ejs_include1.ejs:1:5:1:7 | foo | views/ejs_include1.ejs:1:1:1:10 | <%- foo %> |
|
||||
@@ -553,6 +569,7 @@ edges
|
||||
| projectB/views/subfolder/other.ejs:3:1:3:12 | <%- sinkB %> | projectB/src/index.js:43:16:43:30 | req.query.sinkB | projectB/views/subfolder/other.ejs:3:1:3:12 | <%- sinkB %> | Cross-site scripting vulnerability due to $@. | projectB/src/index.js:43:16:43:30 | req.query.sinkB | user-provided value |
|
||||
| views/angularjs_include.ejs:3:5:3:18 | <%- rawHtml %> | app.js:66:18:66:34 | req.query.rawHtml | views/angularjs_include.ejs:3:5:3:18 | <%- rawHtml %> | Cross-site scripting vulnerability due to $@. | app.js:66:18:66:34 | req.query.rawHtml | user-provided value |
|
||||
| views/angularjs_sinks.ejs:4:9:4:22 | <%- rawHtml %> | app.js:66:18:66:34 | req.query.rawHtml | views/angularjs_sinks.ejs:4:9:4:22 | <%- rawHtml %> | Cross-site scripting vulnerability due to $@. | app.js:66:18:66:34 | req.query.rawHtml | user-provided value |
|
||||
| views/dot_sinks.html.dot:3:9:3:22 | {{! tainted }} | app.js:73:18:73:30 | req.query.foo | views/dot_sinks.html.dot:3:9:3:22 | {{! tainted }} | Cross-site scripting vulnerability due to $@. | app.js:73:18:73:30 | req.query.foo | user-provided value |
|
||||
| views/ejs_include1.ejs:1:1:1:10 | <%- foo %> | app.js:8:18:8:34 | req.query.rawHtml | views/ejs_include1.ejs:1:1:1:10 | <%- foo %> | Cross-site scripting vulnerability due to $@. | app.js:8:18:8:34 | req.query.rawHtml | user-provided value |
|
||||
| views/ejs_include2.ejs:1:1:1:14 | <%- rawHtml %> | app.js:8:18:8:34 | req.query.rawHtml | views/ejs_include2.ejs:1:1:1:14 | <%- rawHtml %> | Cross-site scripting vulnerability due to $@. | app.js:8:18:8:34 | req.query.rawHtml | user-provided value |
|
||||
| views/ejs_sinks.ejs:4:9:4:22 | <%- rawHtml %> | app.js:8:18:8:34 | req.query.rawHtml | views/ejs_sinks.ejs:4:9:4:22 | <%- rawHtml %> | Cross-site scripting vulnerability due to $@. | app.js:8:18:8:34 | req.query.rawHtml | user-provided value |
|
||||
|
||||
@@ -66,3 +66,16 @@ app.get('/angularjs', (req, res) => {
|
||||
rawHtml: req.query.rawHtml,
|
||||
});
|
||||
});
|
||||
|
||||
app.get('/dotjs', (req, res) => {
|
||||
// Currently we don't auto-insert the full .html.dot extension. Test all variations.
|
||||
res.render('dot_sinks.html.dot', {
|
||||
tainted: req.query.foo,
|
||||
});
|
||||
res.render('dot_sinks.html', {
|
||||
tainted: req.query.foo,
|
||||
});
|
||||
res.render('dot_sinks', {
|
||||
tainted: req.query.foo,
|
||||
});
|
||||
});
|
||||
|
||||
@@ -12,6 +12,7 @@ getLikelyTemplateSyntax
|
||||
| projectB/views/subfolder/other.ejs:0:0:0:0 | projectB/views/subfolder/other.ejs | ejs |
|
||||
| views/angularjs_include.ejs:0:0:0:0 | views/angularjs_include.ejs | ejs |
|
||||
| views/angularjs_sinks.ejs:0:0:0:0 | views/angularjs_sinks.ejs | ejs |
|
||||
| views/dot_sinks.html.dot:0:0:0:0 | views/dot_sinks.html.dot | dot |
|
||||
| views/ejs_include1.ejs:0:0:0:0 | views/ejs_include1.ejs | ejs |
|
||||
| views/ejs_include2.ejs:0:0:0:0 | views/ejs_include2.ejs | ejs |
|
||||
| views/ejs_sinks.ejs:0:0:0:0 | views/ejs_sinks.ejs | ejs |
|
||||
@@ -24,6 +25,7 @@ getTargetFile
|
||||
| app.js:25:5:40:6 | res.ren ... \\n }) | views/hbs_sinks.hbs:0:0:0:0 | views/hbs_sinks.hbs |
|
||||
| app.js:44:5:60:6 | res.ren ... \\n }) | views/njk_sinks.njk:0:0:0:0 | views/njk_sinks.njk |
|
||||
| app.js:64:5:67:6 | res.ren ... \\n }) | views/angularjs_sinks.ejs:0:0:0:0 | views/angularjs_sinks.ejs |
|
||||
| app.js:72:5:74:6 | res.ren ... \\n }) | views/dot_sinks.html.dot:0:0:0:0 | views/dot_sinks.html.dot |
|
||||
| consolidate.js:3:1:3:83 | consoli ... => {}) | views/instantiated_as_ejs.html:0:0:0:0 | views/instantiated_as_ejs.html |
|
||||
| consolidate.js:4:1:4:90 | consoli ... => {}) | views/instantiated_as_hbs.html:0:0:0:0 | views/instantiated_as_hbs.html |
|
||||
| projectA/src/index.js:11:5:14:6 | res.ren ... \\n }) | projectA/views/main.ejs:0:0:0:0 | projectA/views/main.ejs |
|
||||
@@ -50,6 +52,7 @@ xssSink
|
||||
| projectB/views/subfolder/other.ejs:3:1:3:12 | <%- sinkB %> |
|
||||
| views/angularjs_include.ejs:3:5:3:18 | <%- rawHtml %> |
|
||||
| views/angularjs_sinks.ejs:4:9:4:22 | <%- rawHtml %> |
|
||||
| views/dot_sinks.html.dot:3:9:3:22 | {{! tainted }} |
|
||||
| views/ejs_include1.ejs:1:1:1:10 | <%- foo %> |
|
||||
| views/ejs_include2.ejs:1:1:1:14 | <%- rawHtml %> |
|
||||
| views/ejs_sinks.ejs:4:9:4:22 | <%- rawHtml %> |
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
<html>
|
||||
<body>
|
||||
{{! tainted }}
|
||||
{{= tainted }}
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user