Skip to content

Instantly share code, notes, and snippets.

@ctcampbell

ctcampbell/pre-request.js

Last active May 18, 2021
Embed
What would you like to do?
Postman pre-request to add Veracode HMAC header
var url = require('url');
var { Property } = require('postman-collection');
const id = pm.variables.get('veracodeApiKeyId');
const key = pm.variables.get('veracodeApiKeySecret');
const authorizationScheme = 'VERACODE-HMAC-SHA-256';
const requestVersion = "vcode_request_version_1";
const nonceSize = 16;
function computeHashHex(message, key_hex) {
return CryptoJS.HmacSHA256(message, CryptoJS.enc.Hex.parse(key_hex)).toString(CryptoJS.enc.Hex);
}
function calulateDataSignature(key, nonceBytes, dateStamp, data) {
let kNonce = computeHashHex(nonceBytes, key);
let kDate = computeHashHex(dateStamp, kNonce);
let kSig = computeHashHex(requestVersion, kDate);
let kFinal = computeHashHex(data, kSig);
return kFinal;
}
function newNonce() {
return CryptoJS.lib.WordArray.random(nonceSize).toString().toUpperCase();
}
function toHexBinary(input) {
return CryptoJS.enc.Hex.stringify(CryptoJS.enc.Utf8.parse(input));
}
function calculateVeracodeAuthHeader(httpMethod, requestUrl) {
let urlExpanded = Property.replaceSubstitutions(requestUrl, pm.variables.toObject());
let parsedUrl = url.parse(urlExpanded);
let data = `id=${id}&host=${parsedUrl.hostname}&url=${parsedUrl.path}&method=${httpMethod}`;
let dateStamp = Date.now().toString();
let nonceBytes = newNonce(nonceSize);
let dataSignature = calulateDataSignature(key, nonceBytes, dateStamp, data);
let authorizationParam = `id=${id},ts=${dateStamp},nonce=${toHexBinary(nonceBytes)},sig=${dataSignature}`;
let header = authorizationScheme + " " + authorizationParam;
return header;
}
pm.request.headers.add({
key: 'Authorization',
value: calculateVeracodeAuthHeader(request['method'], request['url'])
});
@GavinF17

This comment has been minimized.

Copy link

@GavinF17 GavinF17 commented Nov 29, 2019

Found this script very useful working with the API, though I ran into an issue using variables in my URL to prevent having to retype https://analysiscenter.veracode.com/api/5.0/ in each request, as {{URL}}getapplist.do would be passed in to request['url'] and cause issues with the URL parsing.

I got around this by using the replaceSubstitutions function provided in Postman:

var {Property} = require('postman-collection');
const substitutedUrl = Property.replaceSubstitutions(request.url, pm.variables.toObject());
postman.setEnvironmentVariable('hmacAuthHeader', calculateVeracodeAuthHeader(request.method, substitutedUrl));
@ctcampbell

This comment has been minimized.

Copy link
Owner Author

@ctcampbell ctcampbell commented Nov 29, 2019

Thanks for that Gavin, looks useful.

@marleybobs

This comment has been minimized.

Copy link

@marleybobs marleybobs commented Feb 18, 2020

Hi Gavin, this is great - I was struggling to get CryptoJS working to create correct Veracode HMAC headers, but this worked perfectly - cheers!
Just an FYI - at the time of posting this comment, there is a problem with the current build of CryptoJS that creates an error when running 'CryptoJS.lib.WordArray.random'.
(I just replaced it with a random hex generator for the time being.)
See brix/crypto-js#256

@vijayk007

This comment has been minimized.

Copy link

@vijayk007 vijayk007 commented May 13, 2020

cryptoJs is not avaiable in servicenow. I created a script include with hmac 256 filel still not working can anyone help me in working this code

@tjarrettveracode

This comment has been minimized.

Copy link

@tjarrettveracode tjarrettveracode commented May 27, 2020

One additional step that may help with this script: you need to add an additional header called Authorization and set its value to {{hmacAuthHeader}}. This will substitute in the environment variable that is created at the last step of this script, containing the HMAC authorization.

@vijayk007

This comment has been minimized.

Copy link

@vijayk007 vijayk007 commented May 27, 2020

One additional step that may help with this script: you need to add an additional header called Authorization and set its value to {{hmacAuthHeader}}. This will substitute in the environment variable that is created at the last step of this script, containing the HMAC authorization.

Do you have any scriptinclude written for the crypto js or did you used the outof box servicenow global.SncAuthentication to encrypting

@ctcampbell

This comment has been minimized.

Copy link
Owner Author

@ctcampbell ctcampbell commented Apr 20, 2021

One additional step that may help with this script: you need to add an additional header called Authorization and set its value to {{hmacAuthHeader}}. This will substitute in the environment variable that is created at the last step of this script, containing the HMAC authorization.

I've updated the script to do this automatically now, so no need to add a header to each request. Also using variables in URLs works now.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment