javascript.express.security.injection.raw-html-format.raw-html-format

Author
unknown
Download Count*
License
User data flows into the host portion of this manually-constructed HTML. This can introduce a Cross-Site-Scripting (XSS) vulnerability if this comes from user-provided input. Consider using a sanitization library such as DOMPurify to sanitize the HTML within.
Run Locally
Run in CI
Defintion
rules:
- id: raw-html-format
message: User data flows into the host portion of this manually-constructed
HTML. This can introduce a Cross-Site-Scripting (XSS) vulnerability if
this comes from user-provided input. Consider using a sanitization library
such as DOMPurify to sanitize the HTML within.
metadata:
cwe:
- "CWE-79: Improper Neutralization of Input During Web Page Generation
('Cross-site Scripting')"
owasp:
- A07:2017 - Cross-Site Scripting (XSS)
- A03:2021 - Injection
references:
- https://cheatsheetseries.owasp.org/cheatsheets/Cross_Site_Scripting_Prevention_Cheat_Sheet.html
category: security
technology:
- express
cwe2022-top25: true
cwe2021-top25: true
subcategory:
- vuln
likelihood: HIGH
impact: MEDIUM
confidence: MEDIUM
license: Commons Clause License Condition v1.0[LGPL-2.1-only]
languages:
- javascript
- typescript
severity: WARNING
mode: taint
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:
- patterns:
- pattern-either:
- patterns:
- pattern-either:
- pattern: '"$HTMLSTR" + $EXPR'
- pattern: '"$HTMLSTR".concat(...)'
- pattern: util.format($HTMLSTR, ...)
- metavariable-pattern:
metavariable: $HTMLSTR
language: generic
pattern: <$TAG ...
- patterns:
- pattern: |
`...`
- pattern-regex: |
.*<\w+.*
Examples
raw-html-format.js
const express = require('express')
const app = express()
const port = 3000
app.get('/test', async (req, res) => {
// ruleid: raw-html-format
res.send("<h1>" + "message: " + req.query.message + "</h1>");
})
app.post('/test2', async (req, res) => {
// ruleid: raw-html-format
res.send(`<h1>message: ${req.query.message}</h1>`);
})
app.post('/test3', async (req, res) => {
// ruleid: raw-html-format
var html = "<h1>" + "message: " + req.query.message + "</h1>"
res.send(html);
})
app.post('/test4', async (req, res) => {
var html = "<h1> message"
// ruleid: raw-html-format
html = html.concat(req.query.message)
html = html.concat("</h1>")
res.send(html);
})
app.get('/ok', async (req, res) => {
// ok: raw-html-format
res.send("message: " + req.query.message);
})
app.post('/ok2', async (req, res) => {
// ok: raw-html-format
res.send(`message: ${req.query.message}`);
})
app.post('/ok3', async (req, res) => {
// ok: raw-html-format
var data = "message: " + req.query.message;
res.send(data);
})
app.post('/ok4', async (req, res) => {
var data = "message: "
// ok: raw-html-format
data = data.concat(req.query.message)
res.send(data);
})
app.listen(port, () => console.log(`Example app listening at http://localhost:${port}`))
Short Link: https://sg.run/5DO3