From f823a95799dc525fbc48bbf9c6dfccbd597d0b92 Mon Sep 17 00:00:00 2001 From: Ryan Birmingham Date: Fri, 15 May 2020 17:32:34 -0400 Subject: [PATCH 1/3] start sanitize --- caracal.js | 3 +++ handlers/sanitizeHandler.js | 25 +++++++++++++++++++++++++ 2 files changed, 28 insertions(+) create mode 100644 handlers/sanitizeHandler.js diff --git a/caracal.js b/caracal.js index 3568594..6c2c2c8 100644 --- a/caracal.js +++ b/caracal.js @@ -12,6 +12,7 @@ const iipHandler = require('./handlers/iipHandler.js'); const loaderHandler = require('./handlers/loaderHandler.js'); const permissionHandler = require('./handlers/permssionHandler.js'); const dataHandlers = require('./handlers/dataHandlers.js'); +const sanitizeBody = require('./handlers/sanitizeHandler.js') // TODO validation of data var WORKERS = process.env.NUM_THREADS || 4; @@ -57,6 +58,8 @@ app.use('/loader/', loaderHandler); // data, mongo app.use('/data', auth.loginHandler(auth.PUBKEY)); +// sanitize +app.use("/data", sanitizeBody) // slide app.get('/data/Slide/find', dataHandlers.Slide.find); app.get('/data/Slide/find', auth.filterHandler('data', 'userFilter', 'filter')); diff --git a/handlers/sanitizeHandler.js b/handlers/sanitizeHandler.js new file mode 100644 index 0000000..26ebbde --- /dev/null +++ b/handlers/sanitizeHandler.js @@ -0,0 +1,25 @@ +var ERR_ON_SANITIZE = (process.env.ERR_ON_SANITIZE === 'true') || false; + + +String.prototype.replaceAll = function(str1, str2, ignore) +{ + return this.replace(new RegExp(str1.replace(/([\/\,\!\\\^\$\{\}\[\]\(\)\.\*\+\?\|\<\>\-\&])/g,"\\$&"),(ignore?"gi":"g")),(typeof(str2)=="string")?str2.replace(/\$/g,"$$$$"):str2); +} + +function sanitizeBody(req, res, next){ + // handle req body edgecases + if (ERR_ON_SANITIZE){ + if (req.body.indexOf("<") >=0 || req.body.indexOf(">") >=0){ + let e = new Error("Characters < and > are disallowed."); + next(e) + } else { + next() + } + } else { + req.body = req.body.replaceAll("<", "") + req.body = req.body.replaceAll(">", "") + next() + } +} + +module.exports = sanitizeBody; From 6e28690eca255b7b1446bc8679d0fdd2e37dd57e Mon Sep 17 00:00:00 2001 From: Ryan Birmingham Date: Fri, 15 May 2020 17:44:31 -0400 Subject: [PATCH 2/3] show reason for rejection --- handlers/sanitizeHandler.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/handlers/sanitizeHandler.js b/handlers/sanitizeHandler.js index 26ebbde..4e80935 100644 --- a/handlers/sanitizeHandler.js +++ b/handlers/sanitizeHandler.js @@ -10,7 +10,8 @@ function sanitizeBody(req, res, next){ // handle req body edgecases if (ERR_ON_SANITIZE){ if (req.body.indexOf("<") >=0 || req.body.indexOf(">") >=0){ - let e = new Error("Characters < and > are disallowed."); + let e = {'statusCode': 400}; + e.error = 'Characters < and > disallowed in body.'; next(e) } else { next() From 4a3b91b6c28c1333fd819e57ebcd8a0dd180794b Mon Sep 17 00:00:00 2001 From: Ryan Birmingham Date: Fri, 15 May 2020 17:52:09 -0400 Subject: [PATCH 3/3] use builtins for sanitize --- caracal.js | 6 +++--- handlers/authHandlers.js | 2 +- handlers/sanitizeHandler.js | 22 ++++++++-------------- 3 files changed, 12 insertions(+), 18 deletions(-) diff --git a/caracal.js b/caracal.js index 6c2c2c8..bf44059 100644 --- a/caracal.js +++ b/caracal.js @@ -12,7 +12,7 @@ const iipHandler = require('./handlers/iipHandler.js'); const loaderHandler = require('./handlers/loaderHandler.js'); const permissionHandler = require('./handlers/permssionHandler.js'); const dataHandlers = require('./handlers/dataHandlers.js'); -const sanitizeBody = require('./handlers/sanitizeHandler.js') +const sanitizeBody = require('./handlers/sanitizeHandler.js'); // TODO validation of data var WORKERS = process.env.NUM_THREADS || 4; @@ -59,7 +59,7 @@ app.use('/loader/', loaderHandler); // data, mongo app.use('/data', auth.loginHandler(auth.PUBKEY)); // sanitize -app.use("/data", sanitizeBody) +app.use("/data", sanitizeBody); // slide app.get('/data/Slide/find', dataHandlers.Slide.find); app.get('/data/Slide/find', auth.filterHandler('data', 'userFilter', 'filter')); @@ -170,7 +170,7 @@ app.use(function(err, req, res, next) { // wrap strings in a json if (typeof err === 'string' || err instanceof String) { err = {'error': err}; - console.error(err) + console.error(err); } else { console.error(err.error || err.message || err.toString()); } diff --git a/handlers/authHandlers.js b/handlers/authHandlers.js index f67ab27..e748bb6 100644 --- a/handlers/authHandlers.js +++ b/handlers/authHandlers.js @@ -71,7 +71,7 @@ if (DISABLE_SEC && !JWK_URL) { } else { console.error('need JWKS URL (JWK_URL)'); process.exit(1); -} +} const getToken = function(req) { if (req.headers.authorization && diff --git a/handlers/sanitizeHandler.js b/handlers/sanitizeHandler.js index 4e80935..575d07b 100644 --- a/handlers/sanitizeHandler.js +++ b/handlers/sanitizeHandler.js @@ -1,25 +1,19 @@ var ERR_ON_SANITIZE = (process.env.ERR_ON_SANITIZE === 'true') || false; - -String.prototype.replaceAll = function(str1, str2, ignore) -{ - return this.replace(new RegExp(str1.replace(/([\/\,\!\\\^\$\{\}\[\]\(\)\.\*\+\?\|\<\>\-\&])/g,"\\$&"),(ignore?"gi":"g")),(typeof(str2)=="string")?str2.replace(/\$/g,"$$$$"):str2); -} - -function sanitizeBody(req, res, next){ +function sanitizeBody(req, res, next) { // handle req body edgecases - if (ERR_ON_SANITIZE){ - if (req.body.indexOf("<") >=0 || req.body.indexOf(">") >=0){ + if (ERR_ON_SANITIZE) { + if (req.body.indexOf("<") >=0 || req.body.indexOf(">") >=0) { let e = {'statusCode': 400}; e.error = 'Characters < and > disallowed in body.'; - next(e) + next(e); } else { - next() + next(); } } else { - req.body = req.body.replaceAll("<", "") - req.body = req.body.replaceAll(">", "") - next() + req.body = req.body.replace(//g, ""); + next(); } }