1

Is the below safe regex function a safe alternative for a Node.js server regex compare function? Of course I should be writing safe regex, but as a secondary precaution, does the below work? Is 250 milliseconds okay?

const vm = require('vm');

const safeRegex = (strToCheck, regex, flags = 'gi') => {
        if (typeof strToCheck !== 'string') return false;

        const ctx = {
                strToCheck: null,
                regex: null,
                result: null
        };

        ctx.strToCheck = strToCheck;
        ctx.regex = new RegExp(regex, flags);

        const context = vm.createContext(ctx);

        const script = new vm.Script('const result = strToCheck.match(regex);');

        try {
                script.runInContext(context, { timeout: 250 }); // milliseconds
                return context.result === null ? false : true;
        } catch(err) {
                console.log('timeout exceeded; failing');
                return false;
        }
}

module.exports = safeRegex;

console.log(safeRegex('test', 'te'));
console.log(safeRegex('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaac', '^(a+)*b$'));

The above function was inspired from this article: https://www.josephkirwin.com/2016/03/12/nodejs_redos_mitigation/

Gary
  • 909
  • 9
  • 26
  • Given your [previous post](https://stackoverflow.com/questions/63531791/is-there-a-way-to-test-if-my-regex-is-vulnerable-to-catastrophic-backtracking?noredirect=1&lq=1), I'd say just fix your regex instead of turning to workarounds like this. – ggorlen Aug 22 '20 at 15:08
  • @ggorlen, agreed, def. the best approach is to fix my regex, but as a secondary precaution do you think the above is a good idea? – Gary Aug 22 '20 at 16:59
  • I don't think so--I haven't seen this much in the wild. Yes, catastrophic backtracking is a real problem that can cause a denial of service but if you create regexes that you've pre-validated as safe, the added code probably causes more harm than it's worth, adding synchronous overhead and introducing a situation where if you get `false`, you don't really know whether it's because the regex backtracked or didn't match. 250 ms with a `console.log` is a pretty long time and DOS seems feasible. With or without this, you still have to fix the regex to get correct and efficient behavior. – ggorlen Aug 22 '20 at 17:17

0 Answers0