Skip to content

Commit

Permalink
fix theoretically possible ReDoS vulnerabilities
Browse files Browse the repository at this point in the history
  • Loading branch information
zloirock committed Feb 11, 2023
1 parent 17081e2 commit 44cf9e8
Show file tree
Hide file tree
Showing 12 changed files with 101 additions and 11 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@
- Fixed configurability and `ToString` conversion of some accessors
- Added Opera Android 73 compat data mapping
- Added TypeScript definitions to `core-js-builder`
- Added proper error on the excess number of trailing `=` in the `atob` polyfill
- Fixed theoretically possible ReDoS vulnerabilities in `String.prototype.{ trim, trimEnd, trimRight }`, `atob`, and `URL` polyfills in some ancient engines

##### [3.27.2 - 2023.01.19](https://github.com/zloirock/core-js/releases/tag/v3.27.2)
- [`Set` methods proposal](https://github.com/tc39/proposal-set-methods) updates:
Expand Down
1 change: 1 addition & 0 deletions packages/core-js/internals/engine-is-ios.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
var userAgent = require('../internals/engine-user-agent');

// eslint-disable-next-line redos/no-vulnerable -- safe
module.exports = /(?:ipad|iphone|ipod).*applewebkit/i.test(userAgent);
1 change: 1 addition & 0 deletions packages/core-js/internals/error-stack-clear.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ var $Error = Error;
var replace = uncurryThis(''.replace);

var TEST = (function (arg) { return String($Error(arg).stack); })('zxcasd');
// eslint-disable-next-line redos/no-vulnerable -- safe
var V8_OR_CHAKRA_STACK_ENTRY = /\n\s*at [^:]*:[^\n]*/;
var IS_V8_OR_CHAKRA_STACK = V8_OR_CHAKRA_STACK_ENTRY.test(TEST);

Expand Down
1 change: 1 addition & 0 deletions packages/core-js/internals/get-substitution.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ var floor = Math.floor;
var charAt = uncurryThis(''.charAt);
var replace = uncurryThis(''.replace);
var stringSlice = uncurryThis(''.slice);
// eslint-disable-next-line redos/no-vulnerable -- safe
var SUBSTITUTION_SYMBOLS = /\$([$&'`]|\d{1,2}|<[^>]*>)/g;
var SUBSTITUTION_SYMBOLS_NO_NAMED = /\$([$&'`]|\d{1,2})/g;

Expand Down
7 changes: 3 additions & 4 deletions packages/core-js/internals/string-trim.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,15 @@ var toString = require('../internals/to-string');
var whitespaces = require('../internals/whitespaces');

var replace = uncurryThis(''.replace);
var whitespace = '[' + whitespaces + ']';
var ltrim = RegExp('^' + whitespace + whitespace + '*');
var rtrim = RegExp(whitespace + whitespace + '*$');
var ltrim = RegExp('^[' + whitespaces + ']+');
var rtrim = RegExp('(^|[^' + whitespaces + '])[' + whitespaces + ']+$');

// `String.prototype.{ trim, trimStart, trimEnd, trimLeft, trimRight }` methods implementation
var createMethod = function (TYPE) {
return function ($this) {
var string = toString(requireObjectCoercible($this));
if (TYPE & 1) string = replace(string, ltrim, '');
if (TYPE & 2) string = replace(string, rtrim, '');
if (TYPE & 2) string = replace(string, rtrim, '$1');
return string;
};
};
Expand Down
2 changes: 1 addition & 1 deletion packages/core-js/internals/typed-array-constructor.js
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ if (DESCRIPTORS) {
});

module.exports = function (TYPE, wrapper, CLAMPED) {
var BYTES = TYPE.match(/\d+$/)[0] / 8;
var BYTES = TYPE.match(/\d+/)[0] / 8;
var CONSTRUCTOR_NAME = TYPE + (CLAMPED ? 'Clamped' : '') + 'Array';
var GETTER = 'get' + TYPE;
var SETTER = 'set' + TYPE;
Expand Down
2 changes: 1 addition & 1 deletion packages/core-js/modules/web.atob.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ var ctoi = require('../internals/base64-map').ctoi;

var disallowed = /[^\d+/a-z]/i;
var whitespaces = /[\t\n\f\r ]+/g;
var finalEq = /[=]+$/;
var finalEq = /[=]{1,2}$/;

var $atob = getBuiltIn('atob');
var fromCharCode = String.fromCharCode;
Expand Down
6 changes: 4 additions & 2 deletions packages/core-js/modules/web.url.constructor.js
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,8 @@ var HEX = /^[\da-f]+$/i;
/* eslint-disable regexp/no-control-character -- safe */
var FORBIDDEN_HOST_CODE_POINT = /[\0\t\n\r #%/:<>?@[\\\]^|]/;
var FORBIDDEN_HOST_CODE_POINT_EXCLUDING_PERCENT = /[\0\t\n\r #/:<>?@[\\\]^|]/;
var LEADING_AND_TRAILING_C0_CONTROL_OR_SPACE = /^[\u0000-\u0020]+|[\u0000-\u0020]+$/g;
var LEADING_C0_CONTROL_OR_SPACE = /^[\u0000-\u0020]+/;
var TRAILING_C0_CONTROL_OR_SPACE = /(^|[^\u0000-\u0020])[\u0000-\u0020]+$/;
var TAB_AND_NEW_LINE = /[\t\n\r]/g;
/* eslint-enable regexp/no-control-character -- safe */
var EOF;
Expand Down Expand Up @@ -357,7 +358,8 @@ URLState.prototype = {
url.query = null;
url.fragment = null;
url.cannotBeABaseURL = false;
input = replace(input, LEADING_AND_TRAILING_C0_CONTROL_OR_SPACE, '');
input = replace(input, LEADING_C0_CONTROL_OR_SPACE, '');
input = replace(input, TRAILING_C0_CONTROL_OR_SPACE, '$1');
}

input = replace(input, TAB_AND_NEW_LINE, '');
Expand Down
10 changes: 8 additions & 2 deletions tests/eslint/eslint.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ const pluginJSONC = require('eslint-plugin-jsonc');
const pluginN = require('eslint-plugin-n');
const pluginPromise = require('eslint-plugin-promise');
const pluginQUnit = require('eslint-plugin-qunit');
const pluginReDoS = require('eslint-plugin-redos');
const pluginRegExp = require('eslint-plugin-regexp');
const pluginSonarJS = require('eslint-plugin-sonarjs');
const pluginUnicorn = require('eslint-plugin-unicorn');
Expand Down Expand Up @@ -625,8 +626,6 @@ const base = {
'regexp/no-potentially-useless-backreference': ERROR,
// disallow standalone backslashes
'regexp/no-standalone-backslash': ERROR,
// disallow exponential and polynomial backtracking
'regexp/no-super-linear-backtracking': ERROR,
// disallow trivially nested assertions
'regexp/no-trivially-nested-assertion': ERROR,
// disallow nested quantifiers that can be rewritten as one quantifier
Expand Down Expand Up @@ -701,6 +700,8 @@ const base = {
'regexp/unicode-escape': ERROR,
// use the `i` flag if it simplifies the pattern
'regexp/use-ignore-case': ERROR,
// ReDoS vulnerability check
'redos/no-vulnerable': [ERROR, { timeout: 1e3 }],

// disallow function declarations in if statement clauses without using blocks
'es/no-function-declarations-in-if-statement-clauses-without-block': ERROR,
Expand Down Expand Up @@ -1043,6 +1044,8 @@ const nodeDev = {
...forbidES2023BuiltIns,
'es/no-intl-supportedvaluesof': ERROR,
...forbidES2023IntlBuiltIns,
// ReDoS vulnerability check
'redos/no-vulnerable': OFF,
};

const tests = {
Expand Down Expand Up @@ -1071,6 +1074,8 @@ const tests = {
'unicorn/error-message': OFF,
// functions should not have identical implementations
'sonarjs/no-identical-functions': OFF,
// ReDoS vulnerability check
'redos/no-vulnerable': OFF,
// allow Annex B methods for testing
...disable(forbidESAnnexBBuiltIns),
};
Expand Down Expand Up @@ -1270,6 +1275,7 @@ module.exports = [
node: pluginN,
promise: pluginPromise,
qunit: pluginQUnit,
redos: pluginReDoS,
regexp: pluginRegExp,
sonarjs: pluginSonarJS,
unicorn: pluginUnicorn,
Expand Down
77 changes: 77 additions & 0 deletions tests/eslint/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions tests/eslint/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
"eslint-plugin-n": "^15.6.1",
"eslint-plugin-promise": "^6.1.1",
"eslint-plugin-qunit": "^7.3.4",
"eslint-plugin-redos": "^4.4.3",
"eslint-plugin-regexp": "^1.12.0",
"eslint-plugin-sonarjs": "~0.18.0",
"eslint-plugin-unicorn": "^45.0.2",
Expand Down
2 changes: 1 addition & 1 deletion tests/unit-global/es.string.replace.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/* eslint-disable regexp/no-super-linear-backtracking, regexp/no-unused-capturing-group -- required for testing */
/* eslint-disable regexp/no-unused-capturing-group -- required for testing */
import { GLOBAL, NATIVE, STRICT } from '../helpers/constants';
import { patchRegExp$exec } from '../helpers/helpers';

Expand Down

0 comments on commit 44cf9e8

Please sign in to comment.