Potential Directory Traversal in an Express JS App

KG
5 min readJun 4, 2020

The other day while I was on a conflict resolution call with my development team to fix security issues, the two developers started comparing the speed of the products they were developing while we are discussing the performance-related issues of the application. One developer says, “Our app runs fast if we cache all the session data”. The other says “It’s better to use Cookie side storage to get rid of server load”. This led me to do a little research on types of session storage.

Express.js is a framework based on node.js for building web-applications. In the Express.js session can also be maintained in the same way. Session file store is a provision for storing session data in the session file. Session state is a technique that can be used in express applications for storing data about the application user’s session on the server-side.

Basically, the session is storing data about the client on the server-side. It uses cookies to transport relevant session data between the client and the server. Sessions can be maintained through different mechanisms as shown below:

Types Of Sessions

1.Signed Sessions:

Cookie-based sessions: The session data, In this case, is not stored in the back end data store. Instead, it’s serialized, signed with a SECRET KEY, and sent to the client. When the client sends the data back, its integrity is checked for tampering and it is deserialized again on the server. eg. Ruby on rails framework uses it.

2.Stored Sessions: These can be stored in many ways such as:

Cache-based storage sessions: In this scenario, the application stores data in the cache to serve future requests faster. While fetching the data, the application first looks for the data in the cache. If there’s a hit (i.e. if the data is in the cache), it serves the data and if there’s a miss(cache-miss) it fetches the data from a permanent store, stores a copy in the cache, and serves the data to the client.

Database storage sessions: In this scenario, the session data itself is not sent to the client. Instead, a session identifier is used to identify the user’s identity and session which is used by the server to retrieve the relevant session data that is stored in the session store.

File-based sessions: The session will be stored on the server-side in a temporary file with session-id attached to the filename. There are many frameworks such as PHP, Django framework in python, etc.

How’s the title of the blog related till now??

Here it is!!!

Directory traversal means an attacker tries to access files outside of the folder you want to allow him to access.

In the below code snippet, the rootdir is set to “/var/www” and path is importing the path API. The user-supplied input(userinputfilename) is appended to the path directly which will help to retrieve files which are requested by the user.

var rootdir = '/var/www/';
var path = require(‘path’);
var filename = path.join(rootdir, userinputfilename); //user input file name contains the filename which will be given by the user

The below code snippets are from File System adapters for Express JS. The vulnerability is a simple directory traversal when retrieving the file used for the session on the file system.

This code snippet maintains the sessions through files that are stored in the temp folder at the server-side. Be sure to check that the Web server has permissions to read and write to this location. When the user requests the files through his unsanitized user input he’ll be able to retrieve sensitive files from the application eg ../../../../etc/passwd.

var options = helpers.defaults({
path: process.argv[2], //path name is taken from the user.
ttl: process.argv[3]
});
sessionPath: function (options, sessionId) {
return path.join(options.path, sessionId + options.fileExtension);//this leads to path traversal vulnerability as the path given by user is directly appended.
},

Example:

Click here to download codebase for session-file-store

A real-life example

GOGS vulnerability (github.com/gogs/gogs) is vulnerable to remote code execution (RCE) attack. The vulnerability exists due to the ability to forge a ‘session-file’, through directory traversal by allowing unauthenticated users to obtain an admin session. The attacker will be able to traverse through the sesssion files which are stored at the server side (file system session storage) and subsequently allowing remote code to be injected.

Remediation:

The path.normalize() method normalizes the given path, resolving '..' and '.' segments.

When multiple slashes are used in the appliation they are replaced by a single instance of the platform-specific path segment separator.

For example, On Windows:

path.normalize('C:\\abc\\\\def\\xyz\\..\\');
// Returns: 'C:\\abc\\xyz\\'

Compare normalized path with the trusted root directory that was hardcoded/configured in the app (e.g: String.startsWith() function: ).If the comparison fails, it means a path traversal is detected, so fail the request.

In a shared hosting environment, all the websites store their session information in the same location. Since the sessions files are stored in the same location, other websites can access your session files. But you can always change the location of the session file storage. Storing sessions in files is not secure when considering security.

Cookies have a size limit of 4kB. Cookies are stored on the client-side and are temporary. The server can set an expiration time for the cookie, but the client may delete the cookie and its contents before that. Ruby on Rails encrypts cookies by default. The client cannot read or edit the contents of the cookie, without breaking encryption. If you take appropriate care of your secrets, you can consider your Cookie-based session is considered harmless.

Cache based sessions require high availability to prevent situations such as cache stampede. So, it’s not recommended to maintain sessions using cache.

As a quote says, “Small things matter the most”, Improper maintenance of session storage, might lead to remote code execution vulnerability which would create a critical impact on the application.

I believe this read helps you guys. I appreciate each one of you for your valuable time to give it a go. Also, your suggestions are always welcome and if you find anywhere I need to add something simply ping me on twitter. My sincere thanks to Michael for helping me out.

Keep learning new stuff, take care!!

Twitter:-

https://twitter.com/FiShY_0007

--

--