Skip to main content

Node.js security: lessons from the Node.js Security Working Group in triaging vulnerabilities

Écrit par:
wordpress-sync/Node.js-wide-1

6 novembre 2020

0 minutes de lecture

In a previous blog post, I talked about a security disclosure for Fastify Node.js framework to the Node.js Security working group on HackerOne. The disclosure was regarding a Server-side JavaScript code injection vulnerability, resulting in the final conclusion that determined the report to be of no security impact to the Fastify Node.js web application framework, or to its JSON schema validation component fast-json-stringify.

Why would a security report fail to be classified as such?

To answer that let’s have a swift look at the report’s findings and identify some of the challenges it posed for the incident response team on the security working group for Node.js.

The security report detailed a code injection attack that manifests by an attacker being able to manipulate a JSON file that is used as a schema for a request validation logic, and with a proof-of-concept that confirmed the security issue through spawning a reverse shell.

This, however, proved to be not a security issue by itself in Fastify, as was pointed out early on by Fastify maintainer, since this security vulnerability doesn’t manifest dynamically or due to a security bug in the framework code itself. This security issue takes place only when untrusted code is being used as the JSON validation schema—which is most commonly written by the developers themselves—and is not used as a source from user input.

This vulnerability report highlights several challenges that we face in the Node.js Security Working Group as security analysts who need to respond to security incidents:

  1. triaging whether a report is applicable and considered a security bug

  2. triaging the source of a vulnerability

Borderline Node.js security issues

Quickly scanning through the report, it seems that the disclosed security issue is a valid security bug. After all, a proof-of-concept was provided and the attack scenario was confirmed to reproduce while involving the aforementioned component.

That said, careful scrutiny needs to apply in order to understand, not only the attack vector and vulnerability details, but also the intended usage of the said vulnerable component. In Fastify’s case, the library deliberately disallows dynamic JSON parsing of the schema it is provided with to validate requests to mitigate such code injection attacks at runtime.

This, however, leaves the fact that developers are still able to make use of JSON parsing schema that has malicious code such as that provided in the proof-of-concept. But is this really a security vulnerability?

This is where things become uncertain. As far as the Fastify team is concerned, they have stated the security considerations clearly in the project’s documentation regarding the JSON schema configuration input being treated as a trusted source. This responsibility is now left at the hands of the developer and the team that makes use of this library to ensure the trusted input.

Where does the Node.js security vulnerability lie?

Another challenge that seldom slips up is the source of a security vulnerability. In this report, for example, it was made apparent that there are two components in question—both the Node.js fastify web framework, and the JSON parsing library fast-json-stingify. Which one of them should be triaged and treated as the vulnerable component regarding this vulnerability?

On one hand, fastify is merely a component that makes use of another component to perform the JSON schema parsing. On the other hand, fast-json-stringify has no declared design intentions to be secure from all and any input and leaves this concern up to the user.

This challenge becomes clearer in a previous security report that we received as an example use case. In that use case, a Cross-site Scripting (XSS) vulnerability is discovered in an application that renders Excel spreadsheet files as HTML outputs, for which it uses a third-party component to parse the spreadsheet data. There, the XSS vulnerability affects the application itself which fails to sanitize the output data to an HTML page. The vulnerability is not related to the third-party component because that component doesn’t have the knowledge in advance for whether the input data will be used in an HTML output context, or perhaps in a plain CSV file. Therefore, as far as the scope goes for the Excel spreadsheet parsing library, this kind of security vulnerability is not related.

Summary

Triaging security vulnerabilities requires a lot of context and experience, and the conversation between the security researcher and the maintainer of the vulnerable component is critical to understand the context in which the exploitability is possible.

Another challenge is properly assigning security vulnerability scores, also known as the Common Vulnerability Scoring System (CVSS). If you’re interested in more on this topic to help you triage Node.js security vulnerabilities, I previously wrote about the challenges of CVSS and tips on getting it right.