-
Notifications
You must be signed in to change notification settings - Fork 8
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(js): add handlebars XSS rule (#317)
- Loading branch information
Showing
3 changed files
with
80 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
patterns: | ||
- pattern: handlebars.compile($<...>$<NO_ESCAPE>) | ||
filters: | ||
- variable: NO_ESCAPE | ||
detection: javascript_lang_handlebars_no_escape_true | ||
scope: result | ||
auxiliary: | ||
- id: javascript_lang_handlebars_no_escape_true | ||
patterns: | ||
- | | ||
{ noEscape: true } | ||
languages: | ||
- javascript | ||
severity: warning | ||
metadata: | ||
description: "Missing escape of HTML entities in Handlebars template compilation" | ||
remediation_message: | | ||
## Description | ||
As a templating engine, Handlebars generates HTML markup dynamically. | ||
Setting `noEscape` to true disables escaping HTML entities within the template output itself. | ||
This is a security risk as it could lead to Cross-Site Scripting (XSS) vulnerabilities if | ||
the template is from an untrusted source. | ||
## Remediations | ||
❌ Do not set `noEscape` to true when compiling Handlebars templates | ||
## References | ||
- [Handlebars compile docs](https://handlebarsjs.com/api-reference/compilation.html#handlebars-compile-template-options) | ||
- [OWASP XSS Prevention Cheat Sheet](https://cheatsheetseries.owasp.org/cheatsheets/Cross_Site_Scripting_Prevention_Cheat_Sheet.html) | ||
cwe_id: | ||
- 80 | ||
id: javascript_lang_handlebars_no_escape | ||
documentation_url: https://docs.bearer.com/reference/rules/javascript_lang_handlebars_no_escape |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
const { | ||
createNewInvoker, | ||
getEnvironment, | ||
} = require("../../../helper.js") | ||
const { ruleId, ruleFile, testBase } = getEnvironment(__dirname) | ||
|
||
describe(ruleId, () => { | ||
const invoke = createNewInvoker(ruleId, ruleFile, testBase) | ||
|
||
test("handlebars_no_escape", () => { | ||
const testCase = "app.js" | ||
|
||
const results = invoke(testCase) | ||
|
||
expect(results).toEqual({ | ||
Missing: [], | ||
Extra: [] | ||
}) | ||
}) | ||
}) |
23 changes: 23 additions & 0 deletions
23
tests/javascript/lang/handlebars_no_escape/testdata/app.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
import Handlebars from 'handlebars'; | ||
|
||
const handlebars = Handlebars.create(); | ||
|
||
export function bad(templateStr) { | ||
try { | ||
// bearer:expected javascript_lang_handlebars_no_escape | ||
const template = handlebars.compile(templateStr, { noEscape: true }); | ||
|
||
compiledTemplate = template(vars); | ||
} catch (err) { | ||
// ... | ||
} | ||
} | ||
|
||
export function ok(templateStr) { | ||
try { | ||
const template = handlebars.compile(templateStr, { noEscape: false }); | ||
compiledTemplate = template(vars); | ||
} catch (err) { | ||
// ... | ||
} | ||
} |