Path Traveral in WebSocket/Socket.io-file NPM Module (File-Upload Mechanism)

Path Traversal in Socket.io-file NPM Module

CVE-ID: 2020-15779

Versions: <= 2.0.31

Package URL: https://www.npmjs.com/package/socket.io-file

Tested on: node v10.19.0, Socket.io-file v2.0.31, socket.io v2.3.0

Proof of Concept: https://www.exploit-db.com/exploits/48713

During one of my penetration tests for a local military equipment supplier, I faced a web application running on an embedded device that used web sockets to initiate the connection between the server and the client. The client made use of Socket.io.

The web application was relatively small, with only a few entry points that did not seem to be vulnerable. As there were more days for my pentest, I decided to dig deeper and analyze the requests, researching the npm modules used in the web application.

One functionality was a configuration file upload, stored in a folder in the filesystem using the Socket.io-file npm module. Playing around with the requests, I managed to bypass the restrictions and upload a file in a different folder from the expected one.

The upload functionality of Socket.io-file is vulnerable to improper input validation, allowing attackers to bypass upload directory restrictions and upload files to paths of their choice in the underlying system.

Vulnerability Description

The default configuration of Socket.io-file comes with an upload functionality handled by WebSockets. When a user tries to upload a file with the web application, the following client-side request is created:

42["socket.io-file::createFile",{"id":"u_0","name":"testfile.mp3","size":1,"chunkSize":10240,"sent":0,"data":{}}]

In the underlying system, the code in index.js of Socket.io-file merges the file path (supplied by the configuration) with the filename supplied by the user:

if (typeof options.uploadDir === 'string') {
    uploadDir = path.join(options.uploadDir, filename);
}

For example, if the user uploads a file named "testfile.mp3" and the server is configured to store files in the "/home/Documents/socket-app/data" path, the resulting path will be:

Since there is no check on the file name, the upload request can be intercepted, and the file name can be altered to move to different paths in the system:

This request will generate the following path:

This means the file will be created in:

Example Scenario: Example Web Application

Consider an example web application using Socket.io-file for file uploads.

  1. Setup the Example Application:

  2. Exploit the Vulnerability:

    • Use Burp Suite or OWASP Zap to intercept the WebSocket request when uploading a file.

    • Modify the intercepted request to change the file path:

  3. Upload a Malicious File:

    • Create a file with a name that traverses directories, such as "../../../etc/passwd".

    • This request will create a file at "/etc/passwd", potentially overwriting the system file and causing severe security issues.

Issue Replication

To replicate the issue, follow these steps:

  1. Setup a proxy to intercept HTTP and WebSocket requests:

    • Use Burp Suite or OWASP Zap.

  2. Upload a file using the Socket.io-file web application and intercept the WebSocket request.

  3. Change the name parameter by adding ../ and specifying the needed path:

    • This example will create the testfile.mp3 file in the Downloads directory of the current user (our test server stores files in /home/ubuntutest/Documents/socket-app/data).

Remediation

No fix is currently available. Consider using an alternative package until a fix is made available.

Vulnerability Disclosure Timeline

Following the npm guidelines for vulnerability disclosure (“If maintainers are unresponsive after 45 days, npm Security makes the advisory public”), we responsibly disclosed this vulnerability on 18th of May 2020.

Description

A Path Traversal issue was discovered in the socket.io-file package through 2.0.31 for Node.js. The socket.io-file::createFile message uses path.join with ../ in the name option, and the uploadDir and rename options determine the path.

By following these steps, you can reproduce the vulnerability and understand the impact of the path traversal in Socket.io-file.

Last updated