TL;DR: Is it dangerous to have user input used in a require function in Node.js? Can it be used to read files, and if so how can I protect against that?
For example, I have an ExpressJS server running, with an API. The client can make a call to /api/login
, which is then required as ./api/login(.coffee)
:
require('coffee-script')
app = require('express')()
app.all '/api/:func?', (req, res) ->
# Get API function
func = req.params.func
# Check if file exists
fs = require 'fs'
fs.access "./api/#{func}.coffee", fs.F_OK & fs.R_OK, (err) ->
if err
# Send error when invalid call
api = require('./api/error')
else
# !!! Injection ?
api = require('./api/' + func)
# Call API
api(req, res)
I assume that one can't send a request to http://example.net/api/../../../etc/passwd
for example, but I only tested that in my browser, and I'm not sure if my browser handles that. Besides that, I think the worst thing that could happen would be that Node crashes because it can't require such a file.
Are there any security issues here, and how would I block such attacks?
../../../..
is done client-wise or server-wise. If it's client-wise, I need to watch out; if ExpressJS already handles this, it should just point to the root of my public directory