diff --git a/config/passport.js b/config/passport.js index 9032fe1..5379446 100755 --- a/config/passport.js +++ b/config/passport.js @@ -7,6 +7,7 @@ const TwitterStrategy = require('passport-twitter').Strategy const GoogleTokenStrategy = require('passport-google-id-token') const FacebookTokenStrategy = require('passport-facebook-token') const TwitterTokenStrategy = require('passport-twitter-token') +const sanitize = require('mongo-sanitize') const debug = require('debug')('tracman-passport') const env = require('./env/env.js') const mw = require('./middleware.js') @@ -33,7 +34,7 @@ module.exports = (passport) => { }, async (req, email, password, done) => { debug(`Perfoming local login for ${email}`) try { - let user = await User.findOne({'email': email}) + let user = await User.findOne({'email': sanitize(email)}) // No user with that email if (!user) { @@ -143,11 +144,11 @@ module.exports = (passport) => { // Check for unique profileId debug(`Checking for unique account with query ${query}...`) try { - let user = await User.findOne(query) + let existing_user = await User.findOne(query) // Social account already in use - if (existingUser) { - debug(`${service} account already in use with user ${existingUser.id}`) + if (existing_user) { + debug(`${service} account already in use with user ${existing_user.id}`) req.session.flashType = 'warning' req.session.flashMessage = `Another user is already connected to that ${service} account. ` return done() diff --git a/config/routes/account.js b/config/routes/account.js index 6276fec..e2b73b1 100644 --- a/config/routes/account.js +++ b/config/routes/account.js @@ -1,6 +1,7 @@ 'use strict' const mw = require('../middleware.js') +const sanitize = require('mongo-sanitize') const User = require('../models.js').user const mail = require('../mail.js') const env = require('../env/env.js') @@ -100,7 +101,7 @@ router.route('/password/:token') debug('/account/password/:token .all() called') try { let user = await User - .findOne({'auth.passToken': req.params.token}) + .findOne({'auth.passToken': sanitize(req.params.token)}) .where('auth.passTokenExpires').gt(Date.now()) if (!user) { diff --git a/config/routes/auth.js b/config/routes/auth.js index 59c0129..4c97ea0 100755 --- a/config/routes/auth.js +++ b/config/routes/auth.js @@ -6,6 +6,7 @@ const User = require('../models.js').user const crypto = require('crypto') const moment = require('moment') const slugify = require('slug') +const sanitize = require('mongo-sanitize') const debug = require('debug')('tracman-routes-auth') const env = require('../env/env.js') @@ -145,7 +146,7 @@ module.exports = (app, passport) => { // Check if somebody already has that email try { debug(`Searching for user with email ${req.body.email}...`) - let user = await User.findOne({'email': req.body.email}) + let user = await User.findOne({'email': sanitize(req.body.email)}) // User already exists if (user && user.auth.password) { @@ -182,7 +183,7 @@ module.exports = (app, passport) => { (async function checkSlug (s, cb) { try { debug(`Checking to see if slug ${s} is taken...`) - let existingUser = await User.findOne({slug: s}) + let existingUser = await User.findOne({slug: sanitize(s)}) // Slug in use: generate a random one and retry if (existingUser) { @@ -283,7 +284,7 @@ module.exports = (app, passport) => { // Check if somebody has that email try { - let user = await User.findOne({'email': req.body.email}) + let user = await User.findOne({'email': sanitize(req.body.email)}) // No user with that email if (!user) { @@ -298,7 +299,7 @@ module.exports = (app, passport) => { // User with that email does exist } else { debug(`User ${user.id} found with that email. Creating reset token...`) - + // Create reset token try { let [token, expires] = await user.createPassToken() diff --git a/config/routes/map.js b/config/routes/map.js index 1e0ef6a..10266fe 100755 --- a/config/routes/map.js +++ b/config/routes/map.js @@ -3,6 +3,7 @@ const router = require('express').Router() const mw = require('../middleware.js') const env = require('../env/env.js') +const sanitize = require('mongo-sanitize') const User = require('../models.js').user // Redirect to real slug @@ -47,21 +48,25 @@ router.get('/demo', (req, res, next) => { // Show map router.get('/:slug?', async (req, res, next) => { try { - let map_user = await User.findOne({slug: req.params.slug}) - if (!map_user) next() // 404 - else { - var active = '' // For header nav - if (req.user && req.user.id === map_user.id) active = 'map' - res.render('map', { - active: active, - mapuser: map_user, - mapApi: env.googleMapsAPI, - user: req.user, - noFooter: '1', - noHeader: (req.query.noheader) ? req.query.noheader.match(/\d/)[0] : 0, - disp: (req.query.disp) ? req.query.disp.match(/\d/)[0] : 2, // 0=map, 1=streetview, 2=both - newuserurl: (req.query.new) ? env.url + '/map/' + req.params.slug : '' - }) + if (req.params.slug != sanitize(req.params.slug)) { + throw new Error(`Possible injection attempt with slug: ${req.params.slug}`) + } else { + let map_user = await User.findOne({slug: req.params.slug}) + if (!map_user) next() // 404 + else { + var active = '' // For header nav + if (req.user && req.user.id === map_user.id) active = 'map' + res.render('map', { + active: active, + mapuser: map_user, + mapApi: env.googleMapsAPI, + user: req.user, + noFooter: '1', + noHeader: (req.query.noheader) ? req.query.noheader.match(/\d/)[0] : 0, + disp: (req.query.disp) ? req.query.disp.match(/\d/)[0] : 2, // 0=map, 1=streetview, 2=both + newuserurl: (req.query.new) ? env.url + '/map/' + req.params.slug : '' + }) + } } } catch (err) { mw.throwErr(err, req) } }) diff --git a/config/routes/settings.js b/config/routes/settings.js index fabf379..a8074a1 100755 --- a/config/routes/settings.js +++ b/config/routes/settings.js @@ -6,6 +6,7 @@ const mw = require('../middleware.js') const User = require('../models.js').user const mail = require('../mail.js') const env = require('../env/env.js') +const sanitize = require('mongo-sanitize') const debug = require('debug')('tracman-routes-settings') const router = require('express').Router() diff --git a/config/sockets.js b/config/sockets.js index e27422b..278ebf3 100755 --- a/config/sockets.js +++ b/config/sockets.js @@ -2,6 +2,7 @@ // Imports const debug = require('debug')('tracman-sockets') +const sanitize = require('mongo-sanitize') const User = require('./models.js').user // Check for tracking clients @@ -82,7 +83,7 @@ module.exports = { } else { try { // Get loc.usr - let user = await User.findById(loc.usr) + let user = await User.findById(sanitize(loc.usr)) .where('sk32').equals(loc.tok) if (!user) { diff --git a/package-lock.json b/package-lock.json index c0a6078..1ecba8f 100755 --- a/package-lock.json +++ b/package-lock.json @@ -4499,6 +4499,11 @@ "resolved": "https://registry.npmjs.org/moment/-/moment-2.20.1.tgz", "integrity": "sha512-Yh9y73JRljxW5QxN08Fner68eFLxM5ynNOAw2LbIB1YAGeQzZT8QFSUvkAz609Zf+IHhhaUxqZK8dG3W/+HEvg==" }, + "mongo-sanitize": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/mongo-sanitize/-/mongo-sanitize-1.0.0.tgz", + "integrity": "sha1-FeMRMEivvz50RkxOgVaCG4/6wdw=" + }, "mongodb": { "version": "2.2.33", "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-2.2.33.tgz", diff --git a/package.json b/package.json index 3d0151c..34485fa 100755 --- a/package.json +++ b/package.json @@ -19,6 +19,7 @@ "load-google-maps-api": "^1.0.0", "minifier": "^0.8.1", "moment": "^2.18.1", + "mongo-sanitize": "^1.0.0", "mongoose": "^4.11.13", "mongoose-unique-validator": "^1.0.6", "nodemailer": "^4.1.1", diff --git a/server.js b/server.js index 17cb4e9..a22ede7 100755 --- a/server.js +++ b/server.js @@ -169,7 +169,7 @@ let ready_promise_list = [] } } -// CSRF Protection +// CSRF Protection (keep after routes) app.use(csurf({ cookie: true, }))