Require CSRF token for POST requests

This commit is contained in:
Nadav Ivgi 2017-12-18 03:44:03 +02:00
parent f66b6d6b42
commit 1d72beea72
4 changed files with 76 additions and 1 deletions

4
app.js
View File

@ -32,8 +32,10 @@ Object.assign(app.locals, {
// Middlewares
app.get('/favicon.ico', (req, res) => res.sendStatus(204)) // to prevent logging
app.use(require('morgan')('dev'))
app.use(require('cookie-parser')())
app.use(require('body-parser').json())
app.use(require('body-parser').urlencoded({ extended: false }))
app.use(require('csurf')({ cookie: true }))
// Static assets
app.use('/_assets', require('stylus').middleware({ src: conf.static_dir, serve: true }))
@ -80,7 +82,7 @@ app.get('/:rpath(*)', pwrap(async (req, res) => {
else if ('preview' in req.query) await preview.handler(file, res)
else res.render('file', { ...file, preview: await preview.metadata(file) })
else res.render('file', { ...file, csrf: req.csrfToken(), preview: await preview.metadata(file) })
}))
// Normalize errors to HTTP status codes

70
package-lock.json generated
View File

@ -1062,6 +1062,15 @@
"resolved": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz",
"integrity": "sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s="
},
"cookie-parser": {
"version": "1.4.3",
"resolved": "https://registry.npmjs.org/cookie-parser/-/cookie-parser-1.4.3.tgz",
"integrity": "sha1-D+MfoZ0AC5X0qt8fU/3CuKIDuqU=",
"requires": {
"cookie": "0.3.1",
"cookie-signature": "1.0.6"
}
},
"cookie-signature": {
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",
@ -1091,11 +1100,49 @@
"which": "1.3.0"
}
},
"csrf": {
"version": "3.0.6",
"resolved": "https://registry.npmjs.org/csrf/-/csrf-3.0.6.tgz",
"integrity": "sha1-thEg3c7q/JHnbtUxO7XAsmZ7cQo=",
"requires": {
"rndm": "1.2.0",
"tsscmp": "1.0.5",
"uid-safe": "2.1.4"
}
},
"css-parse": {
"version": "1.7.0",
"resolved": "https://registry.npmjs.org/css-parse/-/css-parse-1.7.0.tgz",
"integrity": "sha1-Mh9s9zeCpv91ERE5D8BeLGV9jJs="
},
"csurf": {
"version": "1.9.0",
"resolved": "https://registry.npmjs.org/csurf/-/csurf-1.9.0.tgz",
"integrity": "sha1-SdLGkl/87Ht95VlZfBU/pTM2QTM=",
"requires": {
"cookie": "0.3.1",
"cookie-signature": "1.0.6",
"csrf": "3.0.6",
"http-errors": "1.5.1"
},
"dependencies": {
"http-errors": {
"version": "1.5.1",
"resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.5.1.tgz",
"integrity": "sha1-eIwNLB3iyBuebowBhDtrl+uSB1A=",
"requires": {
"inherits": "2.0.3",
"setprototypeof": "1.0.2",
"statuses": "1.3.1"
}
},
"setprototypeof": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.0.2.tgz",
"integrity": "sha1-gaVSFB7BBLiOic44MQOtXGZWTQg="
}
}
},
"currency-formatter": {
"version": "1.3.1",
"resolved": "https://registry.npmjs.org/currency-formatter/-/currency-formatter-1.3.1.tgz",
@ -2229,6 +2276,11 @@
"resolved": "https://registry.npmjs.org/qs/-/qs-6.5.1.tgz",
"integrity": "sha512-eRzhrN1WSINYCDCbrz796z37LOe3m5tmW7RQf6oBntukAG1nmovJvhnwHHRMAfeoItc1m2Hk02WER2aQ/iqs+A=="
},
"random-bytes": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/random-bytes/-/random-bytes-1.0.0.tgz",
"integrity": "sha1-T2ih3Arli9P7lYSMMDJNt11kNgs="
},
"randomatic": {
"version": "1.1.7",
"resolved": "https://registry.npmjs.org/randomatic/-/randomatic-1.1.7.tgz",
@ -2434,6 +2486,11 @@
"align-text": "0.1.4"
}
},
"rndm": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/rndm/-/rndm-1.2.0.tgz",
"integrity": "sha1-8z/pz7Urv9UgqhgyO8ZdsRCht2w="
},
"safe-buffer": {
"version": "5.1.1",
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz",
@ -2647,6 +2704,11 @@
"integrity": "sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM=",
"dev": true
},
"tsscmp": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/tsscmp/-/tsscmp-1.0.5.tgz",
"integrity": "sha1-fcSjOvcVgatDN9qR2FylQn69mpc="
},
"type-is": {
"version": "1.6.15",
"resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.15.tgz",
@ -2677,6 +2739,14 @@
"integrity": "sha1-bgkk1r2mta/jSeOabWMoUKD4grc=",
"optional": true
},
"uid-safe": {
"version": "2.1.4",
"resolved": "https://registry.npmjs.org/uid-safe/-/uid-safe-2.1.4.tgz",
"integrity": "sha1-Otbzg2jG1MjHXsF2I/t5qh0HHYE=",
"requires": {
"random-bytes": "1.0.0"
}
},
"universalify": {
"version": "0.1.1",
"resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.1.tgz",

View File

@ -12,6 +12,8 @@
"babel-polyfill": "^6.26.0",
"bootswatch": "^4.0.0-beta.2",
"commander": "^2.12.2",
"cookie-parser": "^1.4.3",
"csurf": "^1.9.0",
"currency-formatter": "^1.3.1",
"express": "^4.16.2",
"file-extension": "^4.0.1",

View File

@ -7,6 +7,7 @@
h3 Purchase
//-p This file is available for #{ price.amount } #{ price.currency }.
form(method='post', action='_invoice')
input(type='hidden', name='_csrf', value=csrf)
input(type='hidden', name='file', value=path)
button.btn.btn-primary.btn-lg.pay-btn(type='submit')= attr.buy_button || `Pay ${fcurrency(price)} to access`