Skip to content

Commit

Permalink
Add rule S5852: Using slow regular expressions is security-sensitive (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
vilchik-elena authored Sep 7, 2021
1 parent 3f8d0dd commit f40733a
Show file tree
Hide file tree
Showing 35 changed files with 921 additions and 26 deletions.
4 changes: 2 additions & 2 deletions .cirrus.yml
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ plugin_qa_nodejs_task:
<<: *ONLY_SONARSOURCE_QA
gke_container:
matrix:
- dockerfile: .cirrus/nodejs-10.Dockerfile
- dockerfile: .cirrus/nodejs-12.Dockerfile
- dockerfile: .cirrus/nodejs-12.Dockerfile
- dockerfile: .cirrus/nodejs-14.Dockerfile
- dockerfile: .cirrus/nodejs-16.Dockerfile
Expand Down Expand Up @@ -154,7 +154,7 @@ ruling_task:
<<: *ONLY_SONARSOURCE_QA
gke_container:
matrix:
- dockerfile: .cirrus/nodejs-10.Dockerfile
- dockerfile: .cirrus/nodejs-12.Dockerfile
- dockerfile: .cirrus/nodejs-14.Dockerfile
<<: *CONTAINER_DEFINITION
cpu: 4
Expand Down
22 changes: 0 additions & 22 deletions .cirrus/nodejs-10.Dockerfile

This file was deleted.

2 changes: 2 additions & 0 deletions eslint-bridge/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@
"functional-red-black-tree": "1.0.1",
"regexpp": "3.2.0",
"run-node": "2.0.0",
"scslre": "0.1.6",
"typescript": "4.3.5",
"vue-eslint-parser": "7.6.0"
},
Expand All @@ -79,6 +80,7 @@
"functional-red-black-tree",
"regexpp",
"run-node",
"scslre",
"vue-eslint-parser",
"typescript"
],
Expand Down
2 changes: 2 additions & 0 deletions eslint-bridge/src/rules/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,7 @@ import { rule as regularExpr } from './regular-expr';
import { rule as sessionRegeneration } from './session-regeneration';
import { rule as shorthandPropertyGrouping } from './shorthand-property-grouping';
import { rule as singleCharacterAlternative } from './single-character-alternation';
import { rule as slowRegex } from './slow-regex';
import { rule as sockets } from './sockets';
import { rule as sonarBlockScopedVar } from './sonar-block-scoped-var';
import { rule as sonarMaxLines } from './sonar-max-lines';
Expand Down Expand Up @@ -350,6 +351,7 @@ ruleModules['regular-expr'] = regularExpr;
ruleModules['session-regeneration'] = sessionRegeneration;
ruleModules['shorthand-property-grouping'] = shorthandPropertyGrouping;
ruleModules['single-character-alternation'] = singleCharacterAlternative;
ruleModules['slow-regex'] = slowRegex;
ruleModules['sockets'] = sockets;
ruleModules['sonar-block-scoped-var'] = sonarBlockScopedVar;
ruleModules['sonar-max-lines'] = sonarMaxLines;
Expand Down
41 changes: 41 additions & 0 deletions eslint-bridge/src/rules/slow-regex.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/*
* SonarQube JavaScript Plugin
* Copyright (C) 2011-2021 SonarSource SA
* mailto:info AT sonarsource DOT com
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
// https://sonarsource.github.io/rspec/#/rspec/S5852

import { Rule } from 'eslint';
import { createRegExpRule } from './regex-rule-template';
import { RegExpLiteral } from 'regexpp/ast';
import { analyse } from 'scslre';

const message = `Make sure the regex used here, which is vulnerable to super-linear runtime due to backtracking, cannot lead to denial of service.`;

export const rule: Rule.RuleModule = createRegExpRule(context => {
return {
onRegExpLiteralEnter: (node: RegExpLiteral) => {
const { reports } = analyse(node);
if (reports.length > 0) {
context.report({
message,
node: context.node,
});
}
},
};
});
124 changes: 124 additions & 0 deletions eslint-bridge/tests/rules/slow-regex.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
/*
* SonarQube JavaScript Plugin
* Copyright (C) 2011-2021 SonarSource SA
* mailto:info AT sonarsource DOT com
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import { RuleTesterTs } from '../RuleTesterTs';

const ruleTesterTs = new RuleTesterTs();

import { rule } from 'rules/slow-regex';

ruleTesterTs.run('redos', rule, {
valid: [
{
code: `
/a|b|c/;
/x*x*/;
/a*(ab)*/;
/x*|x*/;
/a*b*/;
`,
},
],
invalid: [
{
code: `
/(a+)+$/
`,
errors: [
{
message: `Make sure the regex used here, which is vulnerable to super-linear runtime due to backtracking, cannot lead to denial of service.`,
line: 2,
endLine: 2,
column: 9,
endColumn: 17,
},
],
},
{
code: `
/([^,]*,)*/; // FP? compliant in SonarJava tests
`,
errors: 1,
},
{
code: `
new RegExp('x*$');
`,
errors: 1,
},
{
// Real vulnerabilities
code: `
protocol.trim().split(/ *, */);
var matcher = /.+\\@.+\\..+/;
enclosure = /[{[].*\\/.*[}\\]]$/;
f.replace(/\\/+$/, '');
regex = /^(?:\\r\\n|\\n|\\r)+|(?:\\r\\n|\\n|\\r)+$/g;
text.replace(/\\033\\[(\\d+)*m/g, '');
/^[\s\u200c]+|[\s\u200c]+$/;
str.replace(/\s*$/, ''); // fixed by next line but it's reported
str.replace(/^\s+|\s+$/g, '');
const entryPattern1 = /^(.)(.*?)\\t(.*?)\\t(.*?)\\t(.*?)\\u000d\\u000a$/
const entryPattern2 = /^(.)([^\\t]*)\\t([^\\t]*)\\t([^\\t]*)\\t([^\\t]*)\\r\\n$/ // OK, fix for previous one
const match = /^data:(?<type>.*?),(?<data>.*?)(?:#(?<hash>.*))?$/.exec(urlString);
const match = /^data:(?<type>[^,]*?),(?<data>[^#]*?)(?:#(?<hash>.*))?$/.exec(urlString); // OK, fix for previous one
`,
errors: [
{
line: 2,
},
{
line: 3,
},
{
line: 4,
},
{
line: 5,
},
{
line: 6,
},
{
line: 7,
},
{
line: 8,
},
{
line: 9,
},
{
line: 10,
},
{
line: 11,
},
{
line: 13,
},
],
},
{
// fails on Node 10
code: `new RegExp('[\\x09\\x0A]*$');`,
errors: 1,
},
],
});
26 changes: 25 additions & 1 deletion eslint-bridge/yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -4382,6 +4382,13 @@ read-pkg@^5.2.0:
parse-json "^5.0.0"
type-fest "^0.6.0"

refa@^0.9.0:
version "0.9.1"
resolved "https://repox.jfrog.io/repox/api/npm/npm/refa/-/refa-0.9.1.tgz#12731fce378d235731b1f73182b20083c8a75ca8"
integrity sha1-EnMfzjeNI1cxsfcxgrIAg8inXKg=
dependencies:
regexpp "^3.2.0"

regenerate-unicode-properties@^8.2.0:
version "8.2.0"
resolved "https://repox.jfrog.io/repox/api/npm/npm/regenerate-unicode-properties/-/regenerate-unicode-properties-8.2.0.tgz#e5de7111d655e7ba60c057dbe9ff37c87e65cdec"
Expand Down Expand Up @@ -4414,7 +4421,15 @@ regex-not@^1.0.0, regex-not@^1.0.2:
extend-shallow "^3.0.2"
safe-regex "^1.1.0"

[email protected], regexpp@^3.1.0:
regexp-ast-analysis@^0.2.3:
version "0.2.4"
resolved "https://repox.jfrog.io/repox/api/npm/npm/regexp-ast-analysis/-/regexp-ast-analysis-0.2.4.tgz#a497a7c8bfbba51438693821e4b0e3ed43e20f1b"
integrity sha1-pJenyL+7pRQ4aTgh5LDj7UPiDxs=
dependencies:
refa "^0.9.0"
regexpp "^3.2.0"

[email protected], regexpp@^3.1.0, regexpp@^3.2.0:
version "3.2.0"
resolved "https://repox.jfrog.io/repox/api/npm/npm/regexpp/-/regexpp-3.2.0.tgz#0425a2768d8f23bad70ca4b90461fa2f1213e1b2"
integrity sha1-BCWido2PI7rXDKS5BGH6LxIT4bI=
Expand Down Expand Up @@ -4576,6 +4591,15 @@ saxes@^5.0.1:
dependencies:
xmlchars "^2.2.0"

[email protected]:
version "0.1.6"
resolved "https://repox.jfrog.io/repox/api/npm/npm/scslre/-/scslre-0.1.6.tgz#71a2832e4bf3a9254973a04fbed90aec94f75757"
integrity sha1-caKDLkvzqSVJc6BPvtkK7JT3V1c=
dependencies:
refa "^0.9.0"
regexp-ast-analysis "^0.2.3"
regexpp "^3.2.0"

"semver@2 || 3 || 4 || 5", semver@^5.5.0:
version "5.7.1"
resolved "https://repox.jfrog.io/repox/api/npm/npm/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7"
Expand Down
11 changes: 11 additions & 0 deletions its/ruling/src/test/expected/js/amplify/javascript-S5852.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
'amplify:lib/amplify.js':[
520,
],
'amplify:lib/amplify.request.js':[
114,
],
'amplify:src/request.js':[
105,
],
}
Loading

0 comments on commit f40733a

Please sign in to comment.