Skip to content

Commit 21bdd7f

Browse files
authored
Merge pull request #137 from github/no-innerHTML
Add no innerHTML rule
2 parents 641649a + 76900cf commit 21bdd7f

File tree

6 files changed

+89
-1
lines changed

6 files changed

+89
-1
lines changed

docs/rules/no-innter-html.md

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
# No `innerHTML`
2+
3+
Using `innerHTML` poses a potential security risk. It should only be used when clearing content.
4+
5+
```js
6+
// bad
7+
function setContent(element, content) {
8+
element.innerHTML = content
9+
}
10+
11+
// good
12+
function clearContent(element) {
13+
element.innerHTML = ''
14+
}
15+
```
16+
17+
## See Also
18+
19+
https://github.com/github/paste-markdown/security/advisories/GHSA-gpfj-4j6g-c4w9

lib/configs/browser.js

+1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ module.exports = {
1010
'github/no-blur': 'error',
1111
'github/no-dataset': 'error',
1212
'github/no-innerText': 'error',
13+
'github/no-inner-html': 'error',
1314
'github/unescaped-html-literal': 'error',
1415
'github/no-useless-passive': 'error',
1516
'github/require-passive-events': 'error',

lib/configs/typescript.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ module.exports = {
66
camelcase: 'off',
77
'no-unused-vars': 'off',
88
'no-shadow': 'off',
9-
'no-invalid-this': "off",
9+
'no-invalid-this': 'off',
1010
'@typescript-eslint/no-invalid-this': ['error'],
1111
'@typescript-eslint/no-shadow': ['error'],
1212
'@typescript-eslint/interface-name-prefix': 'off',

lib/index.js

+1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ module.exports = {
1111
'no-dataset': require('./rules/no-dataset'),
1212
'no-implicit-buggy-globals': require('./rules/no-implicit-buggy-globals'),
1313
'no-innerText': require('./rules/no-innerText'),
14+
'no-inner-html': require('./rules/no-inner-html'),
1415
'no-then': require('./rules/no-then'),
1516
'unescaped-html-literal': require('./rules/unescaped-html-literal'),
1617
'no-useless-passive': require('./rules/no-useless-passive'),

lib/rules/no-inner-html.js

+33
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
module.exports = {
2+
meta: {
3+
type: 'problem',
4+
docs: {
5+
description: 'disallow `Element.prototype.innerHTML``',
6+
url: require('../url')(module)
7+
},
8+
schema: []
9+
},
10+
11+
create(context) {
12+
return {
13+
AssignmentExpression(node) {
14+
if (node.operator === '=') {
15+
const leftNode = node.left
16+
const rightNode = node.right
17+
18+
if (leftNode.property && leftNode.property.name === 'innerHTML') {
19+
if (rightNode.type === 'Literal' && rightNode.value === '') {
20+
return
21+
}
22+
23+
context.report({
24+
node,
25+
message:
26+
'Using innerHTML poses a potential security risk and should not be used other than clearing content.'
27+
})
28+
}
29+
}
30+
}
31+
}
32+
}
33+
}

tests/no-inner-html.js

+34
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
const rule = require('../lib/rules/no-inner-html')
2+
const RuleTester = require('eslint').RuleTester
3+
4+
const ruleTester = new RuleTester()
5+
6+
ruleTester.run('no-innter-html', rule, {
7+
valid: [
8+
{
9+
code: 'document.createElement("js-flash-text").innerHTML = ""'
10+
}
11+
],
12+
invalid: [
13+
{
14+
code: 'document.createElement("js-flash-text").innerHTML = "foo"',
15+
errors: [
16+
{
17+
message:
18+
'Using innerHTML poses a potential security risk and should not be used other than clearing content.',
19+
type: 'AssignmentExpression'
20+
}
21+
]
22+
},
23+
{
24+
code: 'document.querySelector("js-flash-text").innerHTML = "<div>code</div>"',
25+
errors: [
26+
{
27+
message:
28+
'Using innerHTML poses a potential security risk and should not be used other than clearing content.',
29+
type: 'AssignmentExpression'
30+
}
31+
]
32+
}
33+
]
34+
})

0 commit comments

Comments
 (0)