I'm having an issue with my checkmarx report on my node.js code. Checkmarx reports following vulnerability:
The application's Promise embeds untrusted data in the generated output with write, at line 53 of lib\utils\request.utils.js. This untrusted data is embedded straight into the output without proper sanitization or encoding, enabling an attacker to inject malicious code into the output.
The attacker would be able to alter the returned web page by simply providing modified data in the user input split, which is read by the validateClientToken method at line 98 of middleware\authorization.service.js. This input then flows through the code straight to the output web page, without sanitization.
This can enable a Reflected Cross-Site Scripting (XSS) attack.
This is about clientToken, which is provided by user in authorization header and finally passed as an body to make a request to another service.
Here is a snippet of my middleware, where clientToken appears first and checkmarx report vulnerability:
function validateClientToken(req) {
if (_.isEmpty(req.headers.authorization)) {
throw ExceptionBuilder.authException('Required Authorization header is missing')
.build();
}
const clientToken = req.headers.authorization.split(' ')[1];
if (_.isEmpty(clientToken)) {
throw ExceptionBuilder.authException('Provided bearer token is empty')
.build();
}
return clientToken;
}
And this is the place where clientToken is passed to make another call.
function sendRequest(requestOptions, body = null) {
return new Promise((resolve, reject) => {
const isPostWithData = requestOptions && requestOptions.method === 'POST' && body !== null;
if (isPostWithData && (!requestOptions.headers || !requestOptions.headers['Content-Length'])) {
requestOptions = Object.assign({}, requestOptions, {
headers: Object.assign({}, requestOptions.headers, {
'Content-Length': Buffer.byteLength(body),
}),
});
}
let response = '';
const request = HTTPS.request(requestOptions, (res) => {
res.on('data', (chunk) => {
response += chunk;
});
res.on('end', () => {
resolve(response);
});
});
request.on('error', (error) => {
reject(error);
});
if (isPostWithData) {
request.write(body);
}
request.end();
});
}
I tried to use validations (using regex if clientToken contains forbidden characters) and sanitization (replacing forbidden characters with ''), but without any success. Checkmarx still reports vulnerability. I tried to do this both in middleware, where clientToken is captured first and directly before making call to another service.
Any ideas what is wrong?