forked from TryGhost/Ghost
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Lock down theme static directory to not serve templates, markdown and…
… text files. closes TryGhost#942 - insert custom middleware to check for blacklisted files - redirect to express.static if file accepted - if not valid return next() to do nothing - currently black listing .hbs, .txt, .md and .json - debatable which is best, black list or white list, either one will probably need tweaks but erred on side of letting a theme serve unknown types
- Loading branch information
1 parent
6db7e6d
commit 9d114c7
Showing
3 changed files
with
122 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
|
||
var _ = require('underscore'), | ||
express = require('express'), | ||
path = require('path'); | ||
|
||
function isBlackListedFileType(file) { | ||
var blackListedFileTypes = ['.hbs', '.md', '.txt', '.json'], | ||
ext = path.extname(file); | ||
return _.contains(blackListedFileTypes, ext); | ||
} | ||
|
||
var middleware = { | ||
|
||
staticTheme: function (g) { | ||
var ghost = g; | ||
return function blackListStatic(req, res, next) { | ||
if (isBlackListedFileType(req.url)) { | ||
return next(); | ||
} | ||
|
||
return middleware.forwardToExpressStatic(ghost, req, res, next); | ||
}; | ||
}, | ||
|
||
// to allow unit testing | ||
forwardToExpressStatic: function (ghost, req, res, next) { | ||
return express['static'](ghost.paths().activeTheme)(req, res, next); | ||
} | ||
}; | ||
|
||
module.exports = middleware; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
/*globals describe, beforeEach, it*/ | ||
var assert = require('assert'), | ||
should = require('should'), | ||
sinon = require('sinon'), | ||
when = require('when'), | ||
express = require('express'), | ||
middleware = require('../../server/middleware'); | ||
|
||
describe('Middleware', function () { | ||
describe('staticTheme', function () { | ||
var realExpressStatic = express.static; | ||
|
||
beforeEach(function () { | ||
sinon.stub(middleware, 'forwardToExpressStatic').yields(); | ||
}); | ||
|
||
afterEach(function () { | ||
middleware.forwardToExpressStatic.restore(); | ||
}); | ||
|
||
it('should call next if hbs file type', function (done) { | ||
var req = { | ||
url: 'mytemplate.hbs' | ||
}; | ||
|
||
middleware.staticTheme(null)(req, null, function (a) { | ||
should.not.exist(a); | ||
middleware.forwardToExpressStatic.calledOnce.should.be.false; | ||
return done(); | ||
}); | ||
}); | ||
|
||
it('should call next if md file type', function (done) { | ||
var req = { | ||
url: 'README.md' | ||
}; | ||
|
||
middleware.staticTheme(null)(req, null, function (a) { | ||
should.not.exist(a); | ||
middleware.forwardToExpressStatic.calledOnce.should.be.false; | ||
return done(); | ||
}); | ||
}); | ||
|
||
it('should call next if txt file type', function (done) { | ||
var req = { | ||
url: 'LICENSE.txt' | ||
}; | ||
|
||
middleware.staticTheme(null)(req, null, function (a) { | ||
should.not.exist(a); | ||
middleware.forwardToExpressStatic.calledOnce.should.be.false; | ||
return done(); | ||
}); | ||
}); | ||
|
||
it('should call next if json file type', function (done) { | ||
var req = { | ||
url: 'sample.json' | ||
} | ||
|
||
middleware.staticTheme(null)(req, null, function (a) { | ||
should.not.exist(a); | ||
middleware.forwardToExpressStatic.calledOnce.should.be.false; | ||
return done(); | ||
}); | ||
}); | ||
|
||
it('should call express.static if valid file type', function (done) { | ||
var ghostStub = { | ||
paths: function() { | ||
return {activeTheme: 'ACTIVETHEME'}; | ||
} | ||
}; | ||
|
||
var req = { | ||
url: 'myvalidfile.css' | ||
}; | ||
|
||
middleware.staticTheme(ghostStub)(req, null, function (req, res, next) { | ||
middleware.forwardToExpressStatic.calledOnce.should.be.true; | ||
assert.deepEqual(middleware.forwardToExpressStatic.args[0][0], ghostStub); | ||
return done(); | ||
}); | ||
}); | ||
}); | ||
}); | ||
|