diff --git a/package.json b/package.json index 45c9302fe..7094dff78 100644 --- a/package.json +++ b/package.json @@ -172,7 +172,8 @@ "url-parse": "^1.4.1", "uuid": "^3.3.2", "valid-url": "^1.0.9", - "xml2json": "^0.11.2" + "xml2json": "^0.11.2", + "xss": "^1.0.15" }, "devDependencies": { "@commitlint/cli": "^8.3.5", diff --git a/src/server/services/mmLeaderboard.js b/src/server/services/mmLeaderboard.js index b3d812ec7..286e3c14d 100644 --- a/src/server/services/mmLeaderboard.js +++ b/src/server/services/mmLeaderboard.js @@ -3,6 +3,7 @@ * Server-side functions necessary for effective integration with MMLeaderboard */ import { services } from 'topcoder-react-lib'; +import xss from 'xss'; const { api, submissions } = services; @@ -17,13 +18,14 @@ export default class MMLService { */ async getLeaderboard(req, res, next) { try { + const sanitizedId = xss(req.params.id); const m2mToken = await api.getTcM2mToken(); const subSrv = submissions.getService(m2mToken); const reviewIds = await subSrv.getScanReviewIds(); const v5api = api.getApiV5(m2mToken); - const subs = await v5api.get(`/submissions?challengeId=${req.params.id}&page=1&perPage=500`); + const subs = await v5api.get(`/submissions?challengeId=${sanitizedId}&page=1&perPage=500`); return res.send({ - id: req.params.id, + id: sanitizedId, subs: await subs.json(), reviewIds, }); diff --git a/src/server/services/recruitCRM.js b/src/server/services/recruitCRM.js index 87324ea2b..801232d57 100644 --- a/src/server/services/recruitCRM.js +++ b/src/server/services/recruitCRM.js @@ -7,6 +7,7 @@ import qs from 'qs'; import _ from 'lodash'; import { logger, services } from 'topcoder-react-lib'; import Joi from 'joi'; +import xss from 'xss'; import { sendEmailDirect } from './sendGrid'; // import GSheetService from './gSheet'; @@ -186,7 +187,12 @@ export default class RecruitCRMService { */ async getJob(req, res, next) { try { - const response = await fetch(`${this.private.baseUrl}/v1/jobs/${req.params.id}`, { + const sanitizedId = xss(req.params.id); + + if (!/^[a-zA-Z0-9-_]{8,20}$/.test(sanitizedId)) { + return res.status(400).json({ error: 'Invalid job ID format.' }); + } + const response = await fetch(`${this.private.baseUrl}/v1/jobs/${sanitizedId}`, { method: 'GET', headers: { 'Content-Type': req.headers['content-type'], @@ -201,7 +207,7 @@ export default class RecruitCRMService { const error = { error: true, status: response.status, - url: `${this.private.baseUrl}/v1/jobs/${req.params.id}`, + url: `${this.private.baseUrl}/v1/jobs/${sanitizedId}`, errObj: await response.json(), }; logger.error(error);