Skip to content

Commit cb32eae

Browse files
committed
Sync with template-lint
1 parent d876356 commit cb32eae

3 files changed

Lines changed: 43 additions & 129 deletions

File tree

docs/rules/template-no-triple-curlies.md

Lines changed: 6 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -2,61 +2,26 @@
22

33
<!-- end auto-generated rule header -->
44

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.
5+
Usage of triple curly braces to allow raw HTML to be injected into the DOM is a large vector for exploits of your application (especially when the raw HTML is user-controllable). Instead of using `{{{foo}}}`, you should use appropriate helpers or computed properties that return a `SafeString` (via `Ember.String.htmlSafe` generally) and ensure that user-supplied data is properly escaped.
126

137
## Examples
148

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:
9+
This rule **forbids** the following:
3210

3311
```gjs
3412
<template>
35-
{{this.content}}
13+
{{{foo}}}
3614
</template>
3715
```
3816

39-
```gjs
40-
<template>
41-
{{htmlSafe this.sanitizedContent}}
42-
</template>
43-
```
17+
This rule **allows** the following:
4418

4519
```gjs
4620
<template>
47-
<div>{{@text}}</div>
21+
{{foo}}
4822
</template>
4923
```
5024

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-
5925
## References
6026

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/)
27+
- See the [documentation](https://api.emberjs.com/ember/release/functions/@ember%2Ftemplate/htmlSafe) for Ember's `htmlSafe` function

lib/rules/template-no-triple-curlies.js

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,11 @@ module.exports = {
55
docs: {
66
description: 'disallow usage of triple curly brackets (unescaped variables)',
77
category: 'Security',
8-
recommended: false,
98
url: 'https://github.com/ember-cli/eslint-plugin-ember/tree/master/docs/rules/template-no-triple-curlies.md',
109
templateMode: 'both',
1110
},
12-
fixable: null,
1311
schema: [],
14-
messages: {
15-
unsafe:
16-
'Usage of triple curly brackets is unsafe. Use htmlSafe helper if absolutely necessary.',
17-
},
12+
messages: { unsafe: 'Usage of triple curly brackets is unsafe' },
1813
originallyFrom: {
1914
name: 'ember-template-lint',
2015
rule: 'lib/rules/no-triple-curlies.js',
@@ -26,8 +21,6 @@ module.exports = {
2621
create(context) {
2722
return {
2823
GlimmerMustacheStatement(node) {
29-
// Check if the statement is unescaped (triple curlies)
30-
// Use 'trusting' property (escaped is deprecated)
3124
if (node.trusting === true) {
3225
context.report({
3326
node,

tests/lib/rules/template-no-triple-curlies.js

Lines changed: 36 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -5,95 +5,51 @@
55
const rule = require('../../../lib/rules/template-no-triple-curlies');
66
const RuleTester = require('eslint').RuleTester;
77

8-
//------------------------------------------------------------------------------
9-
// Tests
10-
//------------------------------------------------------------------------------
11-
12-
const ruleTester = new RuleTester({
8+
const validHbs = [
9+
'{{foo}}',
10+
'{{! template-lint-disable no-bare-strings }}',
11+
'{{! template-lint-disable }}',
12+
// Upstream also treats `{{! template-lint-disable no-triple-curlies}}{{{lol}}}` as valid,
13+
// but this RuleTester does not honor template-lint disable directives.
14+
];
15+
16+
const invalidHbs = [
17+
{
18+
code: '\n {{{foo}}}',
19+
output: null,
20+
errors: [{ message: 'Usage of triple curly brackets is unsafe' }],
21+
},
22+
];
23+
24+
function wrapTemplate(entry) {
25+
if (typeof entry === 'string') {
26+
return `<template>${entry}</template>`;
27+
}
28+
29+
return {
30+
...entry,
31+
code: `<template>${entry.code}</template>`,
32+
output: entry.output ? `<template>${entry.output}</template>` : entry.output,
33+
errors: entry.errors.map(() => ({ messageId: 'unsafe' })),
34+
};
35+
}
36+
37+
const gjsRuleTester = new RuleTester({
1338
parser: require.resolve('ember-eslint-parser'),
1439
parserOptions: { ecmaVersion: 2022, sourceType: 'module' },
1540
});
1641

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-
],
42+
gjsRuleTester.run('template-no-triple-curlies', rule, {
43+
valid: validHbs.map(wrapTemplate),
44+
invalid: invalidHbs.map(wrapTemplate),
7445
});
7546

7647
const hbsRuleTester = new RuleTester({
7748
parser: require.resolve('ember-eslint-parser/hbs'),
7849
parserOptions: { ecmaVersion: 2022, sourceType: 'module' },
7950
});
8051

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-
],
52+
hbsRuleTester.run('template-no-triple-curlies', rule, {
53+
valid: validHbs,
54+
invalid: invalidHbs,
9955
});

0 commit comments

Comments
 (0)