Skip to content

Commit

Permalink
Moves symlink deny into its own middleware. #646 #659
Browse files Browse the repository at this point in the history
  • Loading branch information
sintaxi committed Jun 6, 2021
1 parent 28611cb commit 5b6af45
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 56 deletions.
2 changes: 1 addition & 1 deletion bin/harp
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ if (argv["_"].length === 1){
var projectPath = path.resolve(process.cwd(), argv["_"][0])
var host = argv.host || '0.0.0.0'
var port = argv.port || 9000
var server = harp.server(projectPath, {})
var server = harp.server(projectPath, argv)

server.listen(port, host, function(error){
if (error) process.exit(1)
Expand Down
43 changes: 3 additions & 40 deletions lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,57 +18,20 @@ var url = require("url")
*
*/

exports.server = function(dirPath, options, callback){
exports.server = function(dirPath, options){
var app = connect()
app.use(middleware.regProjectFinder(dirPath))
app.use(middleware.setup)
app.use(middleware.basicAuth)
app.use(middleware.underscore)

// app.use(function(req, rsp, next){
// var pathname = url.parse(req.url).pathname.replace(/^\/|\/$/g, '')
// if (pathname !== "app.js") return next()
// var setup = helpers.setup(dirPath)
// var results = esbuild.buildSync({
// absWorkingDir: setup.publicPath,
// entryPoints: [setup.publicPath + '/app.jsx'],
// outfile: 'app.js',
// bundle: true,
// write: false,
// plugins: [],
// })
// rsp.statusCode = 200
// rsp.end(results.outputFiles[0]["text"])
// })

// app.use(function(req, rsp, next){
// var pathname = url.parse(req.url).pathname.replace(/^\/|\/$/g, '')
// if (pathname !== "bundle.js") return next()
// var setup = helpers.setup(dirPath)
// var results = esbuild.buildSync({
// absWorkingDir: setup.publicPath,
// entryPoints: [setup.publicPath + '/bundle.cjs'],
// outfile: 'bundle.js',
// bundle: true,
// write: false,
// plugins: [],
// })
// rsp.statusCode = 200
// rsp.end(results.outputFiles[0]["text"])
// })

app.use(middleware.mwl)
app.use(middleware.static)
app.use(middleware.poly)
app.use(middleware.setupPaths)
app.use(middleware.denySymlink(options))
app.use(middleware.process)
app.use(middleware.fallback2)

return app

// return app.listen(options.port || 9966, options.ip, function(){
// app.projectPath = dirPath
// callback.apply(app, arguments)
// })
}


Expand Down
56 changes: 41 additions & 15 deletions lib/middleware.js
Original file line number Diff line number Diff line change
Expand Up @@ -567,6 +567,47 @@ var poly = exports.poly = function(req, rsp, next){
}


exports.setupPaths = function(req, rsp, next){
req.normalizedPath = helpers.normalizeUrl(req.url)
req.priorityList = terraform.helpers.buildPriorityList(req.normalizedPath)
req.sourceFile = terraform.helpers.findFirstFile(req.setup.publicPath, req.priorityList)
return next()
}


/**
* Deny Symlink
*/

exports.denySymlink = function(options){
options = options || {}

return function(req, rsp, next){
if (!req.sourceFile) return next()
if (!options.hasOwnProperty("deny-symlinks")) return next()
if (!options["deny-symlinks"] === false) return next()

req.sourceFilePath = path.join(req.setup.publicPath, req.sourceFile)
fs.lstat(req.sourceFilePath, function(err, stats) {
if (!stats.isSymbolicLink()) return next()
if (stats.isSymbolicLink()) {
fs.readlink(req.sourceFile, function (err, symlinkTo) {
// forbidding access if the symlink points to a file outside of the project's base directory to prevent path traversal
var projectPath = path.dirname(require.main.filename) // full path of the project's main file
var symlinkPath = path.dirname(symlinkTo) // full path of the symlink
if (projectPath !== symlinkPath) {
var body = "403 Forbidden"
rsp.statusCode = 403
rsp.end(body)
}
})
}
})
}

}


/**
* Asset Pipeline
*/
Expand Down Expand Up @@ -609,21 +650,6 @@ exports.process = function(req, rsp, next){
* Now we let terraform handle the asset pipeline.
*/

// checking if the source file being served is a symlink
fs.lstat(sourceFile, function(err, stats) {
if (stats.isSymbolicLink()) {
fs.readlink(sourceFile, function (err, symlinkTo) {
// forbidding access if the symlink points to a file outside of the project's base directory to prevent path traversal
var projectPath = path.dirname(require.main.filename) // full path of the project's main file
var symlinkPath = path.dirname(symlinkTo) // full path of the symlink
if (projectPath !== symlinkPath) {
var body = "403 Forbidden"
rsp.statusCode = 403
rsp.end(body)
}
});
}
});

req.poly.render(sourceFile, function(error, body){
if(error){
Expand Down

0 comments on commit 5b6af45

Please sign in to comment.