2015-02-27 08:57:57 -05:00
Path = require ( " path " )
fs = require ( " fs " )
Settings = require ( " settings-sharelatex " )
logger = require ( " logger-sharelatex " )
url = require " url "
module.exports = ForbidSymlinks = (staticFn, root, options) ->
expressStatic = staticFn root , options
basePath = Path . resolve ( root )
return (req, res, next) ->
path = url . parse ( req . url ) ? . pathname
2015-05-12 10:17:18 -04:00
# check that the path is of the form /project_id_or_name/path/to/file.log
if result = path . match ( /^\/?([a-zA-Z0-9_-]+)\/(.*)/ )
2015-05-11 07:10:13 -04:00
project_id = result [ 1 ]
file = result [ 2 ]
else
logger . warn path: path , " unrecognized file request "
return res . sendStatus ( 404 )
# check that the file does not use a relative path
for dir in file . split ( ' / ' )
if dir == ' .. '
logger . warn path: path , " attempt to use a relative path "
return res . sendStatus ( 404 )
# check that the requested path is normalized
requestedFsPath = " #{ basePath } / #{ project_id } / #{ file } "
if requestedFsPath != Path . normalize ( requestedFsPath )
logger . error path: requestedFsPath , " requestedFsPath is not normalized "
return res . sendStatus ( 404 )
# check that the requested path is not a symlink
2015-02-27 08:57:57 -05:00
fs . realpath requestedFsPath , (err, realFsPath)->
if err ?
if err . code == ' ENOENT '
return res . sendStatus ( 404 )
else
2016-03-31 06:14:39 -04:00
logger . error err : err , requestedFsPath : requestedFsPath , realFsPath : realFsPath , path: req . params [ 0 ] , project_id: req . params . project_id , " error checking file access "
2015-02-27 08:57:57 -05:00
return res . sendStatus ( 500 )
else if requestedFsPath != realFsPath
logger . warn requestedFsPath : requestedFsPath , realFsPath : realFsPath , path: req . params [ 0 ] , project_id: req . params . project_id , " trying to access a different file (symlink), aborting "
return res . sendStatus ( 404 )
else
expressStatic ( req , res , next )