javascript.express.security.express-insecure-template-usage.express-insecure-template-usage
semgrep
Author
unknown
Download Count*
License
User data from $REQ
is being compiled into the template, which can lead to a Server Side Template Injection (SSTI) vulnerability.
Run Locally
Run in CI
Defintion
rules:
- id: express-insecure-template-usage
message: User data from `$REQ` is being compiled into the template, which can
lead to a Server Side Template Injection (SSTI) vulnerability.
options:
interfile: true
metadata:
interfile: true
category: security
cwe:
- "CWE-1336: Improper Neutralization of Special Elements Used in a
Template Engine"
owasp:
- A03:2021 - Injection
- A01:2017 - Injection
references:
- https://cheatsheetseries.owasp.org/cheatsheets/Injection_Prevention_Cheat_Sheet.html
technology:
- javascript
- typescript
- express
- pug
- jade
- dot
- ejs
- nunjucks
- lodash
- handlbars
- mustache
- hogan.js
- eta
- squirrelly
source_rule_url:
- https://github.com/github/codeql/blob/2ba2642c7ab29b9eedef33bcc2b8cd1d203d0c10/javascript/ql/test/query-tests/Security/CWE-094/CodeInjection/template-sinks.js
subcategory:
- vuln
likelihood: MEDIUM
impact: MEDIUM
confidence: MEDIUM
license: Commons Clause License Condition v1.0[LGPL-2.1-only]
vulnerability_class:
- Code Injection
languages:
- javascript
- typescript
severity: WARNING
mode: taint
pattern-propagators:
- pattern: $MODEL.$FIND($E).then((...,$S,...)=>{...})
from: $E
to: $S
pattern-sources:
- patterns:
- pattern-either:
- pattern-inside: function ... ($REQ, $RES) {...}
- pattern-inside: function ... ($REQ, $RES, $NEXT) {...}
- patterns:
- pattern-either:
- pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES) {...})
- pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES, $NEXT) {...})
- metavariable-regex:
metavariable: $METHOD
regex: ^(get|post|put|head|delete|options)$
- pattern-either:
- pattern: $REQ.query
- pattern: $REQ.body
- pattern: $REQ.params
- pattern: $REQ.cookies
- pattern: $REQ.headers
- patterns:
- pattern-either:
- pattern-inside: |
({ $REQ }: Request,$RES: Response, $NEXT: NextFunction) =>
{...}
- pattern-inside: |
({ $REQ }: Request,$RES: Response) => {...}
- focus-metavariable: $REQ
- pattern-either:
- pattern: params
- pattern: query
- pattern: cookies
- pattern: headers
- pattern: body
pattern-sinks:
- pattern-either:
- patterns:
- pattern-either:
- pattern-inside: |
$PUG = require('pug')
...
- pattern-inside: |
import * as $PUG from 'pug'
...
- pattern-inside: |
$PUG = require('jade')
...
- pattern-inside: |
import * as $PUG from 'jade'
...
- pattern-either:
- pattern: $PUG.compile(...)
- pattern: $PUG.compileClient(...)
- pattern: $PUG.compileClientWithDependenciesTracked(...)
- pattern: $PUG.render(...)
- patterns:
- pattern-either:
- pattern-inside: |
$PUG = require('dot')
...
- pattern-inside: |
import * as $PUG from 'dot'
...
- pattern-either:
- pattern: $PUG.template(...)
- pattern: $PUG.compile(...)
- patterns:
- pattern-either:
- pattern-inside: |
$PUG = require('ejs')
...
- pattern-inside: |
import * as $PUG from 'ejs'
...
- pattern-either:
- pattern: $PUG.render(...)
- patterns:
- pattern-either:
- pattern-inside: |
$PUG = require('nunjucks')
...
- pattern-inside: |
import * as $PUG from 'nunjucks'
...
- pattern-either:
- pattern: $PUG.renderString(...)
- patterns:
- pattern-either:
- pattern-inside: |
$PUG = require('lodash')
...
- pattern-inside: |
import * as $PUG from 'lodash'
...
- pattern-either:
- pattern: $PUG.template(...)
- patterns:
- pattern-either:
- pattern-inside: |
$PUG = require('mustache')
...
- pattern-inside: |
import * as $PUG from 'mustache'
...
- pattern-inside: |
$PUG = require('eta')
...
- pattern-inside: |
import * as $PUG from 'eta'
...
- pattern-inside: |
$PUG = require('squirrelly')
...
- pattern-inside: |
import * as $PUG from 'squirrelly'
...
- pattern-either:
- pattern: $PUG.render(...)
- patterns:
- pattern-either:
- pattern-inside: |
$PUG = require('hogan.js')
...
- pattern-inside: |
import * as $PUG from 'hogan.js'
...
- pattern-inside: |
$PUG = require('handlebars')
...
- pattern-inside: |
import * as $PUG from 'handlebars'
...
- pattern-either:
- pattern: $PUG.compile(...)
Examples
express-insecure-template-usage.jsx
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';
import * as handlebars from 'handlebars';
import * as mustache from 'mustache';
const Hogan = require("hogan.js");
import * as Eta from 'eta';
import * as Sqrl from 'squirrelly'
var app = express();
app.get('/', function(req, res) {
let tainted = req.query.id;
// ruleid: express-insecure-template-usage
pug.compile(tainted);
// ruleid: express-insecure-template-usage
pug.render(tainted);
// ruleid: express-insecure-template-usage
jade.compile(tainted);
// ruleid: express-insecure-template-usage
jade.render(tainted);
// ruleid: express-insecure-template-usage
dot.template(tainted);
// ruleid: express-insecure-template-usage
ejs.render(tainted);
// ruleid: express-insecure-template-usage
nunjucks.renderString(tainted);
// ruleid: express-insecure-template-usage
lodash.template(tainted);
// ruleid: express-insecure-template-usage
dot.compile(tainted);
// ruleid: express-insecure-template-usage
handlebars.compile(req.query.id);
// ruleid: express-insecure-template-usage
mustache.render(req.body._);
// ruleid: express-insecure-template-usage
Hogan.compile(tainted);
// ruleid: express-insecure-template-usage
Eta.render(tainted);
// ruleid: express-insecure-template-usage
Sqrl.render(tainted);
});
Short Link: https://sg.run/b49v