diff --git a/app/routes/contributions.js b/app/routes/contributions.js index 7f68170b94..be952a5fed 100644 --- a/app/routes/contributions.js +++ b/app/routes/contributions.js @@ -27,11 +27,10 @@ function ContributionsHandler(db) { this.handleContributionsUpdate = (req, res, next) => { - /*jslint evil: true */ - // Insecure use of eval() to parse inputs - const preTax = eval(req.body.preTax); - const afterTax = eval(req.body.afterTax); - const roth = eval(req.body.roth); + // Secure parsing of numeric inputs + const preTax = parseFloat(req.body.preTax) || 0; + const afterTax = parseFloat(req.body.afterTax) || 0; + const roth = parseFloat(req.body.roth) || 0; /* //Fix for A1 -1 SSJS Injection attacks - uses alternate method to eval diff --git a/app/routes/index.js b/app/routes/index.js index a9e55426bf..a74b3ae538 100644 --- a/app/routes/index.js +++ b/app/routes/index.js @@ -68,8 +68,21 @@ const index = (app, db) => { // Handle redirect for learning resources link app.get("/learn", isLoggedIn, (req, res) => { - // Insecure way to handle redirects by taking redirect url from query string - return res.redirect(req.query.url); + // Secure way to handle redirects with URL validation + const allowedUrls = [ + '/dashboard', + '/profile', + '/courses', + '/tutorials' + ]; + + const redirectUrl = req.query.url; + + if (!redirectUrl || !allowedUrls.includes(redirectUrl)) { + return res.redirect('/dashboard'); // Default safe redirect + } + + return res.redirect(redirectUrl); }); // Research Page diff --git a/app/views/benefits.html b/app/views/benefits.html index 40e9b45bee..35808d34d4 100644 --- a/app/views/benefits.html +++ b/app/views/benefits.html @@ -52,6 +52,7 @@ {{user.lastName}}
+ {% csrf_token %}
diff --git a/app/views/tutorial/a2.html b/app/views/tutorial/a2.html index 9202d86493..25da896dcb 100644 --- a/app/views/tutorial/a2.html +++ b/app/views/tutorial/a2.html @@ -204,7 +204,7 @@

Further Reading

  • Helmet Security header middleware collection for express
  • -
  • Seven Web Server HTTP Headers that Improve Web Application Security for Free +
  • Seven Web Server HTTP Headers that Improve Web Application Security for Free
  • Passport authentication middleware
  • CWE-384: Session Fixation diff --git a/docker-compose.yml b/docker-compose.yml index 49fb28f813..4c99469d4a 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -13,5 +13,15 @@ services: mongo: image: mongo:4.4 user: mongodb + read_only: true + tmpfs: + - /tmp + volumes: + - mongo_data:/data/db + +volumes: + mongo_data: + security_opt: + - no-new-privileges:true expose: - 27017 diff --git a/package.json b/package.json index b2eb65a041..82f4fcd2f4 100644 --- a/package.json +++ b/package.json @@ -6,21 +6,21 @@ "main": "server.js", "dependencies": { "bcrypt-nodejs": "0.0.3", - "body-parser": "^1.15.1", + "body-parser": "^1.20.3", "consolidate": "^0.14.1", "csurf": "^1.8.3", "dont-sniff-mimetype": "^1.0.0", - "express": "^4.13.4", + "express": "^4.19.2", "express-session": "^1.13.0", "forever": "^2.0.0", "helmet": "^2.0.0", - "marked": "0.3.5", - "mongodb": "^2.1.18", + "marked": "4.0.10", + "mongodb": "^3.1.13", "needle": "2.2.4", "node-esapi": "0.0.1", "serve-favicon": "^2.3.0", - "swig": "^1.4.2", - "underscore": "^1.8.3" + "swig": "^2.0.5", + "underscore": "^1.12.1" }, "comments": { "//": "a9 insecure components" @@ -42,7 +42,7 @@ "async": "^2.0.0-rc.4", "cross-env": "^7.0.2", "cypress": "^3.3.1", - "grunt": "^1.0.3", + "grunt": "^1.3.0", "grunt-cli": "^1.2.0", "grunt-concurrent": "^2.3.0", "grunt-contrib-jshint": "^3.0.0", diff --git a/server.js b/server.js index d6bb500a2d..ea93cef1be 100644 --- a/server.js +++ b/server.js @@ -12,7 +12,12 @@ const MongoClient = require("mongodb").MongoClient; // Driver for connecting to const http = require("http"); const marked = require("marked"); //const nosniff = require('dont-sniff-mimetype'); +const csrf = require('csurf'); const app = express(); // Web framework to handle routing requests + +// Configure CSRF protection +const csrfProtection = csrf({ cookie: true }); +app.use(csrfProtection); const routes = require("./app/routes"); const { port, db, cookieSecret } = require("./config/config"); // Application config properties /*