CodeSOD: Evaluating Regexes
Stack V supports a web application that accepts regexes from users. For legacy reasons, the users must supply the surrounding / characters, as well. There was some validation to ensure that the inputs were correct, but QA discovered that invalid regular expressions were getting through.
They filed a bug, it got triaged, and then shipped off to a contractor to patch. This was the contractor's solution:
const isRegex = (string) => { try { // eslint-disable-next-line no-new-func return new Function(` "use strict"; try { new RegExp(${string}); return true; } catch (e) { return false; } `)(); } catch(e) { return false; } };
Here, we use string interpolation to generate some JavaScript code. It tries to construct a regex using our input string, and returns false if it doesn't compile. We then execute that generated code using new Function, which just evals the string. And then, in true "just ship it" contractor fashion, they disable the warning that tells them this is a terrible idea.
The obvious problem here is one of code injection. But there's another problem: it doesn't meet the requirements. Because of some other WTF, the users need to supply /s. But the RegExp constructor also accepts strings, so 'this is my regex' would pass this validation, but would be considered invalid by the application.
This code got kicked back to the contractor, but the contractor claimed that they'd already spent their budget on the work so far, and needed a contract extension to do any more work. While management hashes that out, fixing this bug has moved in-house instead.
[Advertisement] Keep the plebs out of prod. Restrict NuGet feed privileges with ProGet. Learn more.