I’ve recently become interested in real world examples of vulnerabilities in Node.js applications, which allow
I decided to mock up a simple example of user input passed to an eval() execution sink, to demonstrate an injection of a simple web shell into the server. This web shell will only exist within the current node.js process, and will not be written to disk.
This demo application will only allow a single user input selection to keep things simple:
Vulnerable code (user input passed to an eval execution sink):
In this example res.write(‘SSJS Injection’) is injected, and the server will return that string in the page response:
So we can perform arbitrary SSJS injection on this location. What about injecting a web shell that will start up after 5 seconds, listening on TCP/8000?
One line web shell:
Because we are inserting code which will be eval’d by the application, the web shell will not be written to disk, and execution will be performed from the existing node process.
Injection of the web shell (application continues to respond normally):
cat /etc/passwd using the web shell:
ls -la /etc:
This is a really simple example of an application with a SSJS injection vulnerability. Another thing to note is that tools to identify web application vulnerabilities may not have support to detect this vulnerability. At the time of this writing, Burp Suite v1.6.10 did not identify a SSJS injection vulnerability in the demo application.