mirror of
https://github.com/overleaf/overleaf.git
synced 2024-11-21 20:47:08 -05:00
Merge pull request #597 from sharelatex/secure-headers
Add security headers
This commit is contained in:
commit
573b5bedf1
4 changed files with 704 additions and 436 deletions
|
@ -6,6 +6,7 @@ metrics = require('metrics-sharelatex')
|
||||||
crawlerLogger = require('./CrawlerLogger')
|
crawlerLogger = require('./CrawlerLogger')
|
||||||
expressLocals = require('./ExpressLocals')
|
expressLocals = require('./ExpressLocals')
|
||||||
Router = require('../router')
|
Router = require('../router')
|
||||||
|
helmet = require "helmet"
|
||||||
metrics.inc("startup")
|
metrics.inc("startup")
|
||||||
UserSessionsRedis = require('../Features/User/UserSessionsRedis')
|
UserSessionsRedis = require('../Features/User/UserSessionsRedis')
|
||||||
|
|
||||||
|
@ -143,6 +144,17 @@ webRouter.use (req, res, next) ->
|
||||||
res.status(503)
|
res.status(503)
|
||||||
res.render("general/closed", {title:"maintenance"})
|
res.render("general/closed", {title:"maintenance"})
|
||||||
|
|
||||||
|
# add security headers using Helmet
|
||||||
|
webRouter.use (req, res, next) ->
|
||||||
|
isLoggedIn = AuthenticationController.isUserLoggedIn(req)
|
||||||
|
isProjectPage = !!req.path.match('^/project/[a-f0-9]{24}$')
|
||||||
|
|
||||||
|
helmet({ # note that more headers are added by default
|
||||||
|
dnsPrefetchControl: false
|
||||||
|
referrerPolicy: { policy: 'origin-when-cross-origin' }
|
||||||
|
noCache: isLoggedIn || isProjectPage
|
||||||
|
})(req, res, next)
|
||||||
|
|
||||||
profiler = require "v8-profiler"
|
profiler = require "v8-profiler"
|
||||||
privateApiRouter.get "/profile", (req, res) ->
|
privateApiRouter.get "/profile", (req, res) ->
|
||||||
time = parseInt(req.query.time || "1000")
|
time = parseInt(req.query.time || "1000")
|
||||||
|
|
1059
services/web/npm-shrinkwrap.json
generated
1059
services/web/npm-shrinkwrap.json
generated
File diff suppressed because it is too large
Load diff
|
@ -26,6 +26,7 @@
|
||||||
"express": "4.13.0",
|
"express": "4.13.0",
|
||||||
"express-session": "^1.14.2",
|
"express-session": "^1.14.2",
|
||||||
"heapdump": "^0.3.7",
|
"heapdump": "^0.3.7",
|
||||||
|
"helmet": "^3.8.1",
|
||||||
"http-proxy": "^1.8.1",
|
"http-proxy": "^1.8.1",
|
||||||
"ioredis": "^2.4.0",
|
"ioredis": "^2.4.0",
|
||||||
"jade": "~1.3.1",
|
"jade": "~1.3.1",
|
||||||
|
|
|
@ -0,0 +1,70 @@
|
||||||
|
assert = require('chai').assert
|
||||||
|
async = require('async')
|
||||||
|
User = require('./helpers/User')
|
||||||
|
request = require('./helpers/request')
|
||||||
|
|
||||||
|
assert_has_common_headers = (response) ->
|
||||||
|
headers = response.headers
|
||||||
|
assert.equal(headers['x-frame-options'], 'SAMEORIGIN')
|
||||||
|
assert.equal(headers['strict-transport-security'], 'max-age=15552000; includeSubDomains')
|
||||||
|
assert.equal(headers['x-content-type-options'], 'nosniff')
|
||||||
|
assert.equal(headers['x-download-options'], 'noopen')
|
||||||
|
assert.equal(headers['x-xss-protection'], '1; mode=block')
|
||||||
|
assert.equal(headers['referrer-policy'], 'origin-when-cross-origin')
|
||||||
|
|
||||||
|
assert_has_cache_headers = (response) ->
|
||||||
|
headers = response.headers
|
||||||
|
assert.equal(headers['surrogate-control'], 'no-store')
|
||||||
|
assert.equal(headers['cache-control'], 'no-store, no-cache, must-revalidate, proxy-revalidate')
|
||||||
|
assert.equal(headers['pragma'], 'no-cache')
|
||||||
|
assert.equal(headers['expires'], '0')
|
||||||
|
|
||||||
|
assert_has_no_cache_headers = (response) ->
|
||||||
|
headers = response.headers
|
||||||
|
assert.isUndefined(headers['surrogate-control'])
|
||||||
|
assert.isUndefined(headers['cache-control'])
|
||||||
|
assert.isUndefined(headers['pragma'])
|
||||||
|
assert.isUndefined(headers['expires'])
|
||||||
|
|
||||||
|
describe "SecurityHeaders", ->
|
||||||
|
before ->
|
||||||
|
@user = new User()
|
||||||
|
|
||||||
|
it 'should not have x-powered-by header', (done) ->
|
||||||
|
request.get '/', (err, res, body) =>
|
||||||
|
assert.isUndefined(res.headers['x-powered-by'])
|
||||||
|
done()
|
||||||
|
|
||||||
|
it 'should have all common headers', (done) ->
|
||||||
|
request.get '/', (err, res, body) =>
|
||||||
|
assert_has_common_headers res
|
||||||
|
done()
|
||||||
|
|
||||||
|
it 'should not have cache headers on public pages', (done) ->
|
||||||
|
request.get '/', (err, res, body) =>
|
||||||
|
assert_has_no_cache_headers res
|
||||||
|
done()
|
||||||
|
|
||||||
|
it 'should have cache headers when user is logged in', (done) ->
|
||||||
|
async.series [
|
||||||
|
(cb) => @user.login cb
|
||||||
|
(cb) => @user.request.get '/', cb
|
||||||
|
(cb) => @user.logout cb
|
||||||
|
], (err, results) =>
|
||||||
|
main_response = results[1][0]
|
||||||
|
assert_has_cache_headers main_response
|
||||||
|
done()
|
||||||
|
|
||||||
|
it 'should have cache headers on project page', (done) ->
|
||||||
|
async.series [
|
||||||
|
(cb) => @user.login cb
|
||||||
|
(cb) =>
|
||||||
|
@user.createProject "public-project", (error, project_id) =>
|
||||||
|
return done(error) if error?
|
||||||
|
@project_id = project_id
|
||||||
|
@user.makePublic @project_id, "readAndWrite", cb
|
||||||
|
(cb) => @user.logout cb
|
||||||
|
], (err, results) =>
|
||||||
|
request.get "/project/#{@project_id}", (err, res, body) =>
|
||||||
|
assert_has_cache_headers res
|
||||||
|
done()
|
Loading…
Reference in a new issue