Skip to content

Commit d876356

Browse files
committed
Extract rule: template-no-triple-curlies
1 parent 58f47d6 commit d876356

4 files changed

Lines changed: 202 additions & 0 deletions

File tree

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -427,6 +427,7 @@ rules in templates can be disabled with eslint directives with mustache or html
427427
| Name                       | Description | 💼 | 🔧 | 💡 |
428428
| :--------------------------------------------------------------------- | :-------------------------------------------------------------- | :- | :- | :- |
429429
| [template-link-rel-noopener](docs/rules/template-link-rel-noopener.md) | require rel="noopener noreferrer" on links with target="_blank" | | 🔧 | |
430+
| [template-no-triple-curlies](docs/rules/template-no-triple-curlies.md) | disallow usage of triple curly brackets (unescaped variables) | | | |
430431

431432
### Services
432433

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
# ember/template-no-triple-curlies
2+
3+
<!-- end auto-generated rule header -->
4+
5+
Disallows usage of triple curly brackets (unescaped output) in templates.
6+
7+
Triple curly brackets (`{{{ }}}`) render unescaped HTML, which can lead to XSS (Cross-Site Scripting) vulnerabilities if user input is not properly sanitized.
8+
9+
## Rule Details
10+
11+
This rule disallows the use of triple curly brackets for unescaped output. If you need to render HTML, use the `htmlSafe` helper or `SafeString` API with proper sanitization.
12+
13+
## Examples
14+
15+
Examples of **incorrect** code for this rule:
16+
17+
```gjs
18+
<template>
19+
{{{this.content}}}
20+
</template>
21+
```
22+
23+
```gjs
24+
<template>
25+
<div>
26+
{{{@htmlContent}}}
27+
</div>
28+
</template>
29+
```
30+
31+
Examples of **correct** code for this rule:
32+
33+
```gjs
34+
<template>
35+
{{this.content}}
36+
</template>
37+
```
38+
39+
```gjs
40+
<template>
41+
{{htmlSafe this.sanitizedContent}}
42+
</template>
43+
```
44+
45+
```gjs
46+
<template>
47+
<div>{{@text}}</div>
48+
</template>
49+
```
50+
51+
## When Not To Use It
52+
53+
If you are certain that the content being rendered is already sanitized and safe, you may disable this rule. However, this is generally discouraged for security reasons.
54+
55+
## Related Rules
56+
57+
- [no-html-safe](./no-html-safe.md) from eslint-plugin-ember
58+
59+
## References
60+
61+
- [eslint-plugin-ember template-no-triple-curlies](https://github.com/ember-cli/eslint-plugin-ember/blob/master/docs/rules/template-no-triple-curlies.md)
62+
- [Ember.js Security Guide](https://guides.emberjs.com/release/security/)
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
/** @type {import('eslint').Rule.RuleModule} */
2+
module.exports = {
3+
meta: {
4+
type: 'problem',
5+
docs: {
6+
description: 'disallow usage of triple curly brackets (unescaped variables)',
7+
category: 'Security',
8+
recommended: false,
9+
url: 'https://github.com/ember-cli/eslint-plugin-ember/tree/master/docs/rules/template-no-triple-curlies.md',
10+
templateMode: 'both',
11+
},
12+
fixable: null,
13+
schema: [],
14+
messages: {
15+
unsafe:
16+
'Usage of triple curly brackets is unsafe. Use htmlSafe helper if absolutely necessary.',
17+
},
18+
originallyFrom: {
19+
name: 'ember-template-lint',
20+
rule: 'lib/rules/no-triple-curlies.js',
21+
docs: 'docs/rule/no-triple-curlies.md',
22+
tests: 'test/unit/rules/no-triple-curlies-test.js',
23+
},
24+
},
25+
26+
create(context) {
27+
return {
28+
GlimmerMustacheStatement(node) {
29+
// Check if the statement is unescaped (triple curlies)
30+
// Use 'trusting' property (escaped is deprecated)
31+
if (node.trusting === true) {
32+
context.report({
33+
node,
34+
messageId: 'unsafe',
35+
});
36+
}
37+
},
38+
};
39+
},
40+
};
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
//------------------------------------------------------------------------------
2+
// Requirements
3+
//------------------------------------------------------------------------------
4+
5+
const rule = require('../../../lib/rules/template-no-triple-curlies');
6+
const RuleTester = require('eslint').RuleTester;
7+
8+
//------------------------------------------------------------------------------
9+
// Tests
10+
//------------------------------------------------------------------------------
11+
12+
const ruleTester = new RuleTester({
13+
parser: require.resolve('ember-eslint-parser'),
14+
parserOptions: { ecmaVersion: 2022, sourceType: 'module' },
15+
});
16+
17+
ruleTester.run('template-no-triple-curlies', rule, {
18+
valid: [
19+
`<template>
20+
{{this.content}}
21+
</template>`,
22+
`<template>
23+
<div>{{@text}}</div>
24+
</template>`,
25+
`<template>
26+
{{htmlSafe this.content}}
27+
</template>`,
28+
29+
'<template>{{foo}}</template>',
30+
],
31+
32+
invalid: [
33+
{
34+
code: `<template>
35+
{{{this.content}}}
36+
</template>`,
37+
output: null,
38+
errors: [
39+
{
40+
message:
41+
'Usage of triple curly brackets is unsafe. Use htmlSafe helper if absolutely necessary.',
42+
type: 'GlimmerMustacheStatement',
43+
},
44+
],
45+
},
46+
{
47+
code: `<template>
48+
<div>
49+
{{{@htmlContent}}}
50+
</div>
51+
</template>`,
52+
output: null,
53+
errors: [
54+
{
55+
message:
56+
'Usage of triple curly brackets is unsafe. Use htmlSafe helper if absolutely necessary.',
57+
type: 'GlimmerMustacheStatement',
58+
},
59+
],
60+
},
61+
62+
{
63+
code: `<template>
64+
{{{foo}}}</template>`,
65+
output: null,
66+
errors: [
67+
{
68+
message:
69+
'Usage of triple curly brackets is unsafe. Use htmlSafe helper if absolutely necessary.',
70+
},
71+
],
72+
},
73+
],
74+
});
75+
76+
const hbsRuleTester = new RuleTester({
77+
parser: require.resolve('ember-eslint-parser/hbs'),
78+
parserOptions: { ecmaVersion: 2022, sourceType: 'module' },
79+
});
80+
81+
hbsRuleTester.run('template-no-triple-curlies (hbs)', rule, {
82+
valid: [
83+
'{{foo}}',
84+
'{{! template-lint-disable no-bare-strings }}',
85+
'{{! template-lint-disable }}',
86+
],
87+
invalid: [
88+
{
89+
code: '\n {{{foo}}}',
90+
output: null,
91+
errors: [
92+
{
93+
message:
94+
'Usage of triple curly brackets is unsafe. Use htmlSafe helper if absolutely necessary.',
95+
},
96+
],
97+
},
98+
],
99+
});

0 commit comments

Comments
 (0)