Node.js and NPM Ecosystem: What are the Security Stakes?

Vladimir de Turckheim, Software Engineer, Sqreen twitter, linkedin
abstract slides video

For vulnerabilities, a SQL injection example is given as well as regular expression denial of service, the latter of which can be found by vuln-regex-detector.

The most interesting, JavaScript-specific vulnerability described was object injection, which occurs when an application expects data of a certain type to be provided (e.g. a number or string), but instead a different type (e.g. a JavaScript object) is provided, significantly changing the behavior of the code.

app.post(‘/documents/find’, (req, res) => {
 const query = { };
 if (req.body.title) query.title = req.body.title;
 if (req.body.desiredType) query.type = req.body.desiredType;
 Document.find(query).exec()
  .then((r) => res.json(r));
}

In this code, an endpoint is querying a NoSQL database, expecting req.body to have a value like { desiredType: 'blog'}, which would result in the query: { type: "blog" }.

However, if an attacker provided an input like { desiredType: { $ne: 0 } }, the resulting query would be { type: { $ne: 0 } }. Since the type field in the database is a string, all records’ type fields will not be equal to 0 ($ne: 0), so all records will be returned, like a NoSQL version of or 1=1.

Ecosystem attacks: most NPM libraries have a huge number of direct and indirect dependencies, which exposes a large supply chain attack surface. Vladimir discusses when ESLint was backdoored as an example.

Recommendations:

  • Keep NodeJS up to date

  • Review any use of critical core modules – carefully sanitize any user input that reaches fs, child_process, and vm

  • Data validation is not native in JavaScript, sanitize inputs using a library like joi

  • Monitor your dependencies for known issues

  • Monitor your dependency tree (anvaka) – some libraries that perform the same functionality have significantly fewer dependencies than others. Minimize your attack surface.





Source link