From 3d45129ce1d375e51ddfb64ed624c2a0162b6ea5 Mon Sep 17 00:00:00 2001 From: Georg-Notebook Date: Fri, 28 May 2021 21:14:06 +0200 Subject: [PATCH] CSRF Protection --- .idea/workspace.xml | 44 ++++++++++++++++++++ package-lock.json | 99 +++++++++++++++++++++++++++++++++++++++++++++ package.json | 1 + server.js | 21 +++++++--- views/login.ejs | 1 + 5 files changed, 161 insertions(+), 5 deletions(-) create mode 100644 .idea/workspace.xml diff --git a/.idea/workspace.xml b/.idea/workspace.xml new file mode 100644 index 0000000..714a96f --- /dev/null +++ b/.idea/workspace.xml @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + + + + + + + + + + 1621799132070 + + + + + + \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index d66ed4f..6166461 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5,12 +5,14 @@ "requires": true, "packages": { "": { + "name": "express-4.x-local-example", "version": "0.0.0", "license": "Unlicense", "dependencies": { "body-parser": "^1.19.0", "connect-ensure-login": "^0.1.1", "cookie-session": "^1.4.0", + "csurf": "^1.11.0", "ejs": "^2.6.2", "express": "^4.17.1", "express-session": "^1.16.1", @@ -172,6 +174,53 @@ "node": ">= 0.8" } }, + "node_modules/csrf": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/csrf/-/csrf-3.1.0.tgz", + "integrity": "sha512-uTqEnCvWRk042asU6JtapDTcJeeailFy4ydOQS28bj1hcLnYRiqi8SsD2jS412AY1I/4qdOwWZun774iqywf9w==", + "dependencies": { + "rndm": "1.2.0", + "tsscmp": "1.0.6", + "uid-safe": "2.1.5" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/csurf": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/csurf/-/csurf-1.11.0.tgz", + "integrity": "sha512-UCtehyEExKTxgiu8UHdGvHj4tnpE/Qctue03Giq5gPgMQ9cg/ciod5blZQ5a4uCEenNQjxyGuzygLdKUmee/bQ==", + "dependencies": { + "cookie": "0.4.0", + "cookie-signature": "1.0.6", + "csrf": "3.1.0", + "http-errors": "~1.7.3" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/csurf/node_modules/http-errors": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.3.tgz", + "integrity": "sha512-ZTTX0MWrsQ2ZAhA1cejAwDLycFsd7I7nVtnkT3Ol0aqodaKW+0CTZDQ1uBv5whptCnc8e8HeRRJxRs0kmm/Qfw==", + "dependencies": { + "depd": "~1.1.2", + "inherits": "2.0.4", + "setprototypeof": "1.1.1", + "statuses": ">= 1.5.0 < 2", + "toidentifier": "1.0.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/csurf/node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, "node_modules/debug": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", @@ -695,6 +744,11 @@ "node": ">= 0.8" } }, + "node_modules/rndm": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/rndm/-/rndm-1.2.0.tgz", + "integrity": "sha1-8z/pz7Urv9UgqhgyO8ZdsRCht2w=" + }, "node_modules/safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", @@ -943,6 +997,46 @@ } } }, + "csrf": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/csrf/-/csrf-3.1.0.tgz", + "integrity": "sha512-uTqEnCvWRk042asU6JtapDTcJeeailFy4ydOQS28bj1hcLnYRiqi8SsD2jS412AY1I/4qdOwWZun774iqywf9w==", + "requires": { + "rndm": "1.2.0", + "tsscmp": "1.0.6", + "uid-safe": "2.1.5" + } + }, + "csurf": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/csurf/-/csurf-1.11.0.tgz", + "integrity": "sha512-UCtehyEExKTxgiu8UHdGvHj4tnpE/Qctue03Giq5gPgMQ9cg/ciod5blZQ5a4uCEenNQjxyGuzygLdKUmee/bQ==", + "requires": { + "cookie": "0.4.0", + "cookie-signature": "1.0.6", + "csrf": "3.1.0", + "http-errors": "~1.7.3" + }, + "dependencies": { + "http-errors": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.3.tgz", + "integrity": "sha512-ZTTX0MWrsQ2ZAhA1cejAwDLycFsd7I7nVtnkT3Ol0aqodaKW+0CTZDQ1uBv5whptCnc8e8HeRRJxRs0kmm/Qfw==", + "requires": { + "depd": "~1.1.2", + "inherits": "2.0.4", + "setprototypeof": "1.1.1", + "statuses": ">= 1.5.0 < 2", + "toidentifier": "1.0.0" + } + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + } + } + }, "debug": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", @@ -1332,6 +1426,11 @@ "unpipe": "1.0.0" } }, + "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.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", diff --git a/package.json b/package.json index 05d0bcd..e5ec190 100644 --- a/package.json +++ b/package.json @@ -21,6 +21,7 @@ "body-parser": "^1.19.0", "connect-ensure-login": "^0.1.1", "cookie-session": "^1.4.0", + "csurf": "^1.11.0", "ejs": "^2.6.2", "express": "^4.17.1", "express-session": "^1.16.1", diff --git a/server.js b/server.js index cd0219a..575af7d 100644 --- a/server.js +++ b/server.js @@ -9,6 +9,13 @@ var GoogleStrategy = require('passport-google-oauth').OAuth2Strategy; //Digest var DigestStrategy = require('passport-http').DigestStrategy +// NO CSRF +var bodyParser = require('body-parser') +var csrf = require('csurf') +var csrfProtection = csrf({ cookie: true }) +var cookieParser = require('cookie-parser') +var parseForm = bodyParser.urlencoded({ extended: false }) + passport.use(new DigestStrategy({ qop: 'auth' }, function(username, done) { db.users.findByUsername(username, function (err, user) { @@ -98,9 +105,12 @@ app.set('view engine', 'ejs'); // Use application-level middleware for common functionality, including // logging, parsing, and session handling. app.use(require('morgan')('combined')); -app.use(require('body-parser').urlencoded({ extended: true })); +// app.use(require('body-parser').urlencoded({ extended: true })); app.use(require('express-session')({ secret: 'keyboard cat', resave: false, saveUninitialized: false })); +// parse cookies +// we need this because "cookie" is true in csrfProtection +app.use(cookieParser()) // Initialize Passport and restore authentication state, if any, from the @@ -109,19 +119,20 @@ app.use(passport.initialize()); app.use(passport.session()); - // Define routes. app.get('/', function(req, res) { res.render('home', { user: req.user }); }); -app.get('/login', +app.get('/login', csrfProtection, function(req, res){ - res.render('login'); + console.log("CSRF TOKEN") + console.log(req.csrfToken()) + res.render('login', {csrfToken: req.csrfToken()}); }); -app.post('/login', +app.post('/login', parseForm, csrfProtection, passport.authenticate('local', { failureRedirect: '/login' }), function(req, res) { res.redirect('/'); diff --git a/views/login.ejs b/views/login.ejs index 353c4d9..e32843f 100644 --- a/views/login.ejs +++ b/views/login.ejs @@ -1,4 +1,5 @@
+