The file system, or fs
, module in Node.js enables file system operations. It gives us access to methods like:
chmod()
to change file permissionsmkdir()
to create directoriesrmdir()
to delete directories- And many more
The fs
module coupled with improperly sanitized user input gives attackers access to our entire file system and exposes it to path traversal and file inclusion vulnerabilities. Take a look at the code below:
const user_input = "./example.txt"; fs.unlinkSync(user_input);
The above example uses unlink()
to delete the file defined by the user’s input. It could be any file on our system! To mitigate the risk, we can tweak our code to restrict traversal scope to a directory of our choice:
const user_input = "example.txt" const root_directory = process.cwd(); // Hard-code path to restrict scope const filePath = path.join(root_directory , fileName); fs.unlinkSync(filePath);
We use the join()
method of the path
method to combine our desired directory with the user-provided file name. Hiding the directory the server is operating on makes it tougher to reach valuable information.
Instructions
Run the provided web application with the terminal command node app.js
. You may need to refresh the integrated browser window afterward.
This application takes as input the file path from the web page form and responds with the contents of the file if it exists. Try experimenting with some file paths such as: example.txt
, src/index.html
, or even /proc/cpuinfo
.
Click Check Work to move on to the next checkpoint.
Let’s secure this path traversal vulnerability!
On line 19 of app.js, assign to filePath
the full path of a file using the path.join()
method which should have the path of the current working directory as the first argument and the name
of the file as the second argument.
Click “Check Work”, use CTRL / CMD + C in the terminal to close the application, and rerun it with node app.js
. Feel free to retry the inputs from the first checkpoint.