diff --git a/lib/http-routes/api/create-call.js b/lib/http-routes/api/create-call.js index af1440fc..0b6d918f 100644 --- a/lib/http-routes/api/create-call.js +++ b/lib/http-routes/api/create-call.js @@ -5,7 +5,7 @@ const CallInfo = require('../../session/call-info'); const {CallDirection, CallStatus} = require('../../utils/constants'); const uuidv4 = require('uuid-random'); const SipError = require('drachtio-srf').SipError; -const { validationResult } = require('express-validator'); +const { validationResult, body } = require('express-validator'); const { validate } = require('@jambonz/verb-specifications'); const sysError = require('./error'); const HttpRequestor = require('../../utils/http-requestor'); @@ -13,7 +13,7 @@ const WsRequestor = require('../../utils/ws-requestor'); const RootSpan = require('../../utils/call-tracer'); const dbUtils = require('../../utils/db-utils'); const { mergeSdpMedia, extractSdpMedia } = require('../../utils/sdp-utils'); -const { createCallSchema } = require('../schemas/create-call'); +const { createCallSchema, customSanitizeFunction } = require('../schemas/create-call'); const removeNullProperties = (obj) => (Object.keys(obj).forEach((key) => obj[key] === null && delete obj[key]), obj); const removeNulls = (req, res, next) => { @@ -24,6 +24,12 @@ const removeNulls = (req, res, next) => { router.post('/', removeNulls, createCallSchema, + body('tag').custom((value) => { + if (value) { + customSanitizeFunction(value); + } + return true; + }), async(req, res) => { const {logger} = req.app.locals; const errors = validationResult(req); diff --git a/lib/http-routes/schemas/create-call.js b/lib/http-routes/schemas/create-call.js index 3820335c..ff9314aa 100644 --- a/lib/http-routes/schemas/create-call.js +++ b/lib/http-routes/schemas/create-call.js @@ -46,11 +46,6 @@ const createCallSchema = checkSchema({ optional: true, errorMessage: 'Invalid tag', }, - 'tag.*': { - trim: true, - escape: true, - stripLow: true, - }, app_json: { isString: true, optional: true, @@ -109,6 +104,34 @@ const createCallSchema = checkSchema({ } }, ['body']); -module.exports = { - createCallSchema +const customSanitizeFunction = (value) => { + try { + if (Array.isArray(value)) { + value = value.map((item) => customSanitizeFunction(item)); + } else if (typeof value === 'object') { + Object.keys(value).forEach((key) => { + value[key] = customSanitizeFunction(value[key]); + }); + } else if (typeof value === 'string') { + /* trims characters at the beginning and at the end of a string */ + value = value.trim(); + + /* We don't escape URLs but verify them via new URL */ + if (value.includes('http')) { + value = new URL(value).toString(); + } else { + /* replaces <, >, &, ', " and / with their corresponding HTML entities */ + value = escape(value); + } + } + } catch (error) { + value = `Error: ${error.message}`; + } + + return value; +}; + +module.exports = { + createCallSchema, + customSanitizeFunction };