Skip to main content

Example SRM script for HMAC signing

This example script for Scriptable Request Modification (SRM) signs a request with HMAC. To support this script, Veracode provides the Crypto.js library.

Ensure you have read the SRM script requirements.

The script contains two credentials variables defined with the names key_id and key_secret. For your script, the logic for generating an HMAC header might vary.

const id = vc.variables['key_id'];
const key = vc.variables['key_secret'];

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(request) {
let data = `id=${id}&host=${request.getHost()}&url=${request.uri}&method=${request.method}`;
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;
}

function run() {
let hmacSignedHeader = calculateVeracodeAuthHeader(request);
request.addHeader('Authorization', hmacSignedHeader);
};

In this example, the global object named request is available to scripts upon each call to the initial run() function. The following sections describe the functions and properties of this global object.

Request object properties

This table describes the properties of the request object.

PropertyTypeDescription
methodStringHTTP method for this request. The value is usually a GET or POST, but other common values are PUT, PATCH, and DELETE.
uriStringStandard URI portion of the HTTP request message. The value is the filepath or endpoint of the request, without the host, port, or protocol. For example, a request to the URL https://example.com/path/file.html has a URI of /path/file.html. You can modify the URI to change the target, endpoint, or to add URL parameters.
versionStringVersion of the HTTP request. The value is commonly HTTP/1.1. Veracode does not recommend changing this value.
headersArrayOne or more HTTP headers associated with the current request. The objects in the array are instances of a Header class that has its own properties. You can modify this array as-is or use helper methods on the request object to more easily modify the headers. Veracode recommends that you only use this property for read-only operations.
bodyIntegerBody message for the HTTP request. The body contains a series of bytes encoded in UTF-8, by default, unless the request headers specify a different encoding.

Request object functions

This table describes the functions, methods, and return type for the request object.

FunctionTypeDescription
getHost()StringReturns the host name of the host receiving the request. A Host header also contains this value. Veracode does not recommend changing the header value because this does not change the target host and it can cause the request to fail.
addHeader(name, value)NullAdds a header to the header array for this request. If a header with the specified name already exists, this method adds an additional header with the same name. Optionally, you can use this method to send multiple headers with the same name.
setHeader(name, value)NullSets a header with the provided name in the header array to the provided value. If one or more headers with the provided name already exists, this function removes the headers before setting this value. For example, if there are multiple headers with the same name, this function removes the headers after a call to this method, and leaves only one header with the given name.
removeHeader(name)NullRemoves all headers with the given name from the header array for this request. If multiple headers with the given name already exist, this function removes all headers with the same name.

Header object properties

This table describes the properties of the header object.

PropertyTypeDescription
nameStringName of a header.
valueStringValue associated with a header.