Skip to main content

Using webhooks with DAST Essentials

You can use webhooks with DAST Essentials to integrate dynamic analysis into your CI/CD pipelines. You can create a custom webhook in a target to run an automated security scan after a deployment or other triggers.

Create a webhook

  1. In DAST Essentials, go to the Target list page.
  2. Select a target, then select Configure.
  3. Select the Integrations tab.
  4. To see the instructions and example code you can use to create a webhook, select a DevOps pipeline integration.

You can now send a POST request to the webhook whenever you want to start a scan for the target. The following examples demonstrate how to send a request and download results.

Example: Webhook with HMAC authentication

To successfully call Veracode webhook endpoints, the HTTP authorization header of each request must include an additional HMAC signature.

You can use any of the existing libraries listed in this section or use the following examples provided as bash scripts.

To run the webhook manually, you can use the following bash script.

#!/usr/bin/env bash

#### Setup variables ####

# Stop the script as soon as the first command fails
set -euo pipefail

# Set WEBHOOK to webhook secret (without URL)
WEBHOOK=$1

# Set the Veracode API ID
API_ID=$2

# Set the Veracode API SECRET
API_SECRET=$3

# Set the API endpoint

# Set the API endpoint
# Use “api.veracode.com” for US instance or “api.veracode.eu” for EU instance
API_ENDPOINT="api.veracode.com"
API_PATH="dae/api/core-api/webhook"

generate_hmac_header() {
VERACODE_AUTH_SCHEMA="VERACODE-HMAC-SHA-256"
VERACODE_API_VERSION="vcode_request_version_1"
$signing_data=$1
nonce="$(cat /dev/random | xxd -p | head -c 32)"
timestamp=$(date +%s"000")

nonce_key=$(echo "$nonce" | xxd -r -p | openssl dgst -sha256 -mac HMAC -macopt hexkey:"$API_SECRET" | awk -F" " '{ print $2 }')
time_key=$(echo -n "$timestamp" | openssl dgst -sha256 -mac HMAC -macopt hexkey:"$nonce_key" | awk -F" " '{ print $2 }')
sig_key=$(echo -n "$VERACODE_API_VERSION" | openssl dgst -sha256 -mac HMAC -macopt hexkey:"$time_key" | awk -F" " '{ print $2 }')
signature=$(echo -n "$signing_data" | openssl dgst -sha256 -mac HMAC -macopt hexkey:"$sig_key" | awk -F" " '{ print $2 }')

echo "$VERACODE_AUTH_SCHEMA id=$API_ID,ts=$timestamp,nonce=$nonce,sig=$signature"
}
#### Start Security Scan ####

# Start Scan and get scan ID

signing_data="id=$API_ID&host=$API_ENDPOINT&url=$API_PATH/$WEBHOOK&method=POST"

VERACODE_AUTH_HEADER=$(generate_hmac_header $signing_data)

`curl -X POST -H "Authorization: $VERACODE_AUTH_HEADER" --data "" https://$API_ENDPOINT/$API_PATH/$WEBHOOK`

Example: Webhook with authentication and a payload

You can send a request that includes a payload and authentication data. In the following example, the payload is an API specification file for an API scan target. DAST Essentials uses the data to configure your target before you start the scan.

note

This request overwrites the user credentials and stores them for the subsequent scan.

To send a webhook request with payload data, run the following cURL command:

curl -X POST -H "content-type: application/json" -H "Authorization: $VERACODE_AUTH_HEADER" --data YOUR_PAYLOAD https://$API_ENDPOINT/$API_PATH/$WEBHOOK`

Where, YOUR_PAYLOAD must match the following example syntax:

{   
"system_authentication": {
"basic_auth": {
"username": "username",
"password": "password"
}
},
"application_authentication": [
{
"username": "username",
"password": "password",
"url": "example.com/login"
}
],
"parameter_authentication": [
{
"type": "HEADER",
"key": "Authorization",
"value": "Bearer 12345678"
}
],
"specs": {
"api_spec": {
"swagger": "2.0",
"info": [],
"host": "api.example.com",
"basePath": "/v1",
"schemes": [
"https"
],
"paths": []
}
}
}

For api_spec, you can enter the entire contents of an API specification file.

Because application_authentication require UI-based sign in, you cannot use it with API scan targets.

Example: Retrieve scan reports

You can use a webhook to retrieve a report of the results in JUnit XML format.

The following example script starts a scan and periodically polls the status of the scan. When the scan is complete, DAST Essentials downloads the report to the file report.xml. To use this example script, you must install curl and jq.

#!/usr/bin/env sh  

#### Setup variables ####

# Stop the script as soon as the first command fails
set -euo pipefail

# Set WEBHOOK to webhook secret (without URL)
WEBHOOK=$1

# Set the Veracode API ID
API_ID=$2

# Set the Veracode API SECRET
API_SECRET=$3

# Set the API endpoint
# Use “api.veracode.com” for US instance or “api.veracode.eu” for EU instance
API_ENDPOINT="api.veracode.com"
API_PATH="dae/api/core-api/webhook"

mkdir -p test-reports

generate_hmac_header() {
VERACODE_AUTH_SCHEMA="VERACODE-HMAC-SHA-256"
VERACODE_API_VERSION="vcode_request_version_1"
signing_data=$1

nonce="$(cat /dev/random | xxd -p | head -c 32)"
timestamp=$(date +%s"000")

nonce_key=$(echo "$nonce" | xxd -r -p | openssl dgst -sha256 -mac HMAC -macopt hexkey:"$API_SECRET" | awk -F" " '{ print $2 }')
time_key=$(echo -n "$timestamp" | openssl dgst -sha256 -mac HMAC -macopt hexkey:"$nonce_key" | awk -F" " '{ print $2 }')
sig_key=$(echo -n "$VERACODE_API_VERSION" | openssl dgst -sha256 -mac HMAC -macopt hexkey:"$time_key" | awk -F" " '{ print $2 }')
signature=$(echo -n "$signing_data" | openssl dgst -sha256 -mac HMAC -macopt hexkey:"$sig_key" | awk -F" " '{ print $2 }')

echo "$VERACODE_AUTH_SCHEMA id=$API_ID,ts=$timestamp,nonce=$nonce,sig=$signature"
}

#### Start Security Scan ####

signing_data="id=$API_ID&host=$API_ENDPOINT&url=$API_PATH/$WEBHOOK&method=POST"

VERACODE_AUTH_HEADER=$(generate_hmac_header $signing_data)

SCAN_ID=`curl --silent -X POST -H "Authorization: $VERACODE_AUTH_HEADER" --data "" https://$API_ENDPOINT/$API_PATH/$WEBHOOK | jq .data.scanId`

# Check if a positive integer was returned as SCAN_ID
if ! [ $SCAN_ID -ge 0 ] 2>/dev/null
then
  echo "Could not start Scan for Webhook $WEBHOOK."
  exit 1
fi

echo "Started Scan for Webhook $WEBHOOK. Scan ID is $SCAN_ID."

#### Check Security Scan Status ####

# Set status to Queued (100)
STATUS=100

# Run the scan until the status is not queued (100) or running (101) anymore
while [ $STATUS -le 101 ]
do
  echo "Scan Status currently is $STATUS (101 = Running)"

   # Only poll every minute
  sleep 60

signing_data="id=$API_ID&host=$API_ENDPOINT&url=$API_PATH/$WEBHOOK/scans/$SCAN_ID/status&method=GET"

VERACODE_AUTH_HEADER=$(generate_hmac_header $signing_data)

   # Refresh status
   STATUS=`curl --silent -H "Authorization: $VERACODE_AUTH_HEADER" https://$API_ENDPOINT/$API_PATH/$WEBHOOK/scans/$SCAN_ID/status | jq .data.status.status_code`

done

echo "Scan finished with status $STATUS."

#### Download Scan Report ####

signing_data="id=$API_ID&host=$API_ENDPOINT&url=$API_PATH/$WEBHOOK/scans/$SCAN_ID/report/junit&method=GET"

VERACODE_AUTH_HEADER=$(generate_hmac_header $signing_data)

curl --silent -H "Authorization: $VERACODE_AUTH_HEADER" https://$API_ENDPOINT/$API_PATH/$WEBHOOK/scans/$SCAN_ID/report/junit -o test-reports/report.xml
echo "Downloaded Report to test-reports/report.xml"

Example: Webhook request responses

The responses are in JSON.

{"message": "webhook_scan_started", "data": {"scanId": SCAN_ID}}    # Success Case  
{"message": "Scan is already running"} # Failure Case