@lipemat/eslint-config 5.0.0-beta.3 → 5.0.0-beta.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/index.js +8 -8
- package/package.json +1 -1
- package/plugins/security/index.js +15 -17
- package/plugins/security/rules/dangerously-set-inner-html.js +18 -4
- package/plugins/security/rules/html-executing-assignment.js +0 -1
- package/plugins/security/rules/html-executing-function.js +0 -1
- package/plugins/security/rules/jquery-executing.js +0 -1
- package/plugins/security/rules/vulnerable-tag-stripping.js +0 -1
- package/plugins/security/utils/shared.js +4 -1
- package/types/plugins/security/index.d.ts +1 -1
- package/types/plugins/security/rules/dangerously-set-inner-html.d.ts +2 -1
- package/types/plugins/security/utils/shared.d.ts +1 -1
package/index.js
CHANGED
|
@@ -7,10 +7,6 @@ import globals from 'globals';
|
|
|
7
7
|
import stylisticTs from '@stylistic/eslint-plugin-ts';
|
|
8
8
|
import { getConfig } from './helpers/config.js';
|
|
9
9
|
const flatCompat = new FlatCompat();
|
|
10
|
-
/**
|
|
11
|
-
* Default config if no extensions override it.
|
|
12
|
-
*
|
|
13
|
-
*/
|
|
14
10
|
const BASE_CONFIG = {
|
|
15
11
|
languageOptions: {
|
|
16
12
|
ecmaVersion: 7,
|
|
@@ -115,16 +111,20 @@ const TS_CONFIG = {
|
|
|
115
111
|
/**
|
|
116
112
|
* Merge in any extensions' config.
|
|
117
113
|
*/
|
|
118
|
-
|
|
114
|
+
const defaultConfig = [
|
|
115
|
+
BASE_CONFIG,
|
|
116
|
+
TS_CONFIG,
|
|
117
|
+
securityPlugin.configs.recommended,
|
|
118
|
+
];
|
|
119
|
+
let mergedConfig = [];
|
|
119
120
|
try {
|
|
120
|
-
mergedConfig = getConfig(
|
|
121
|
+
mergedConfig = getConfig(defaultConfig);
|
|
121
122
|
}
|
|
122
123
|
catch (e) {
|
|
124
|
+
// JS Boilerplate is likely not installed.
|
|
123
125
|
console.debug(e);
|
|
124
|
-
// JS Boilerplate is not installed.
|
|
125
126
|
}
|
|
126
127
|
export default [
|
|
127
|
-
...securityPlugin.configs.recommended,
|
|
128
128
|
...fixupConfigRules(flatCompat.extends('plugin:@wordpress/eslint-plugin/recommended-with-formatting')),
|
|
129
129
|
...fixupConfigRules(flatCompat.extends('plugin:deprecation/recommended')),
|
|
130
130
|
...mergedConfig,
|
package/package.json
CHANGED
|
@@ -25,27 +25,25 @@ const plugin = {
|
|
|
25
25
|
'window-escaping': windowEscaping,
|
|
26
26
|
},
|
|
27
27
|
configs: {
|
|
28
|
-
recommended:
|
|
28
|
+
recommended: {},
|
|
29
29
|
},
|
|
30
30
|
};
|
|
31
31
|
// Freeze the plugin to prevent modifications and use the plugin within.
|
|
32
32
|
plugin.configs = Object.freeze({
|
|
33
|
-
recommended:
|
|
34
|
-
{
|
|
35
|
-
|
|
36
|
-
'@lipemat/security': plugin,
|
|
37
|
-
},
|
|
38
|
-
rules: {
|
|
39
|
-
'@lipemat/security/dangerously-set-inner-html': 'error',
|
|
40
|
-
'@lipemat/security/html-executing-assignment': 'error',
|
|
41
|
-
'@lipemat/security/html-executing-function': 'error',
|
|
42
|
-
'@lipemat/security/html-sinks': 'error',
|
|
43
|
-
'@lipemat/security/html-string-concat': 'error',
|
|
44
|
-
'@lipemat/security/jquery-executing': 'error',
|
|
45
|
-
'@lipemat/security/vulnerable-tag-stripping': 'error',
|
|
46
|
-
'@lipemat/security/window-escaping': 'error',
|
|
47
|
-
},
|
|
33
|
+
recommended: {
|
|
34
|
+
plugins: {
|
|
35
|
+
'@lipemat/security': plugin,
|
|
48
36
|
},
|
|
49
|
-
|
|
37
|
+
rules: {
|
|
38
|
+
'@lipemat/security/dangerously-set-inner-html': 'error',
|
|
39
|
+
'@lipemat/security/html-executing-assignment': 'error',
|
|
40
|
+
'@lipemat/security/html-executing-function': 'error',
|
|
41
|
+
'@lipemat/security/html-sinks': 'error',
|
|
42
|
+
'@lipemat/security/html-string-concat': 'error',
|
|
43
|
+
'@lipemat/security/jquery-executing': 'error',
|
|
44
|
+
'@lipemat/security/vulnerable-tag-stripping': 'error',
|
|
45
|
+
'@lipemat/security/window-escaping': 'error',
|
|
46
|
+
},
|
|
47
|
+
},
|
|
50
48
|
});
|
|
51
49
|
export default plugin;
|
|
@@ -29,12 +29,15 @@ const plugin = {
|
|
|
29
29
|
defaultOptions: [],
|
|
30
30
|
meta: {
|
|
31
31
|
type: 'problem',
|
|
32
|
-
|
|
32
|
+
hasSuggestions: true,
|
|
33
33
|
docs: {
|
|
34
34
|
description: 'Disallow using unsanitized values in dangerouslySetInnerHTML',
|
|
35
35
|
},
|
|
36
36
|
messages: {
|
|
37
37
|
dangerousInnerHtml: 'Any HTML passed to `dangerouslySetInnerHTML` gets executed. Please make sure it\'s properly escaped.',
|
|
38
|
+
// Suggestions
|
|
39
|
+
domPurify: 'Wrap the content with a `DOMPurify.sanitize()` call.',
|
|
40
|
+
sanitize: 'Wrap the content with a `sanitize()` call.',
|
|
38
41
|
},
|
|
39
42
|
schema: [],
|
|
40
43
|
},
|
|
@@ -51,9 +54,20 @@ const plugin = {
|
|
|
51
54
|
context.report({
|
|
52
55
|
node,
|
|
53
56
|
messageId: 'dangerousInnerHtml',
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
+
suggest: [
|
|
58
|
+
{
|
|
59
|
+
messageId: 'domPurify',
|
|
60
|
+
fix: (fixer) => {
|
|
61
|
+
return fixer.replaceText(node, `dangerouslySetInnerHTML={{__html: DOMPurify.sanitize( ${context.sourceCode.getText(htmlValue)} )}}`);
|
|
62
|
+
},
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
messageId: 'sanitize',
|
|
66
|
+
fix: (fixer) => {
|
|
67
|
+
return fixer.replaceText(node, `dangerouslySetInnerHTML={{__html: sanitize( ${context.sourceCode.getText(htmlValue)} )}}`);
|
|
68
|
+
},
|
|
69
|
+
},
|
|
70
|
+
],
|
|
57
71
|
});
|
|
58
72
|
},
|
|
59
73
|
};
|
|
@@ -13,7 +13,6 @@ const plugin = {
|
|
|
13
13
|
docs: {
|
|
14
14
|
description: 'Disallow using unsanitized values in HTML executing property assignments',
|
|
15
15
|
},
|
|
16
|
-
fixable: 'code',
|
|
17
16
|
hasSuggestions: true,
|
|
18
17
|
messages: {
|
|
19
18
|
executed: 'Any HTML used with `{{propertyName}}` gets executed. Make sure it\'s properly escaped.',
|
|
@@ -64,7 +64,6 @@ const plugin = {
|
|
|
64
64
|
docs: {
|
|
65
65
|
description: 'Disallow using unsanitized values in functions that execute HTML',
|
|
66
66
|
},
|
|
67
|
-
fixable: 'code',
|
|
68
67
|
hasSuggestions: true,
|
|
69
68
|
messages: {
|
|
70
69
|
'document.write': 'Any HTML used with `document.write` gets executed. Make sure it\'s properly escaped.',
|
|
@@ -55,7 +55,6 @@ const plugin = {
|
|
|
55
55
|
docs: {
|
|
56
56
|
description: 'Disallow using unsanitized values in jQuery methods that execute HTML',
|
|
57
57
|
},
|
|
58
|
-
fixable: 'code',
|
|
59
58
|
hasSuggestions: true,
|
|
60
59
|
messages: {
|
|
61
60
|
needsEscaping: 'Any HTML used with `{{methodName}}` gets executed. Make sure it\'s properly escaped.',
|
|
@@ -33,7 +33,6 @@ const plugin = {
|
|
|
33
33
|
docs: {
|
|
34
34
|
description: 'Disallow jQuery .html().text() chaining which can lead to XSS through tag stripping',
|
|
35
35
|
},
|
|
36
|
-
fixable: 'code',
|
|
37
36
|
hasSuggestions: true,
|
|
38
37
|
messages: {
|
|
39
38
|
vulnerableTagStripping: 'Using .html().text() can lead to XSS vulnerabilities through tag stripping. Use only .text()',
|
|
@@ -63,11 +63,14 @@ export function isLiteralString(node) {
|
|
|
63
63
|
}
|
|
64
64
|
/**
|
|
65
65
|
* Check if a node is a literal string that is safe to use in an HTML context.
|
|
66
|
-
* - Must be a literal string.
|
|
66
|
+
* - Must be a literal string. Or a conditional expression where both branches are safe literal strings.
|
|
67
67
|
* - Must not contain `<script`.
|
|
68
68
|
* - Must not start with a dangerous protocol (javascript:, data:, vbscript:, about:, livescript:).
|
|
69
69
|
*/
|
|
70
70
|
export function isSafeLiteralString(node) {
|
|
71
|
+
if (AST_NODE_TYPES.ConditionalExpression === node.type) {
|
|
72
|
+
return isSafeLiteralString(node.consequent) && isSafeLiteralString(node.alternate);
|
|
73
|
+
}
|
|
71
74
|
if (!isLiteralString(node)) {
|
|
72
75
|
return false;
|
|
73
76
|
}
|
|
@@ -32,7 +32,7 @@ export declare function isSanitized(node: TSESTree.Property['value'] | TSESTree.
|
|
|
32
32
|
export declare function isLiteralString(node: TSESTree.Property['value'] | TSESTree.CallExpressionArgument): node is TSESTree.StringLiteral;
|
|
33
33
|
/**
|
|
34
34
|
* Check if a node is a literal string that is safe to use in an HTML context.
|
|
35
|
-
* - Must be a literal string.
|
|
35
|
+
* - Must be a literal string. Or a conditional expression where both branches are safe literal strings.
|
|
36
36
|
* - Must not contain `<script`.
|
|
37
37
|
* - Must not start with a dangerous protocol (javascript:, data:, vbscript:, about:, livescript:).
|
|
38
38
|
*/
|