Using Webhooks - Start DevSecOps

How to use webhooks to script the Crashtest Security Suite functionalities. Allows integration in your continuous integration / continuous deployment (CI/CD) pipeline to pentest every release.

To run an automated security scan after a deployment (or other triggers), you can create a custom webhook in the project settings. This page explains how to create a webhook and the different payloads that you can execute.

We also have a complete example of a Circle CI pipeline setup, an app that is deployed via Circle CI, as well as running our scans for every deployment here. You can also define different rules for passing or failing builds.

If there is a picture with source code, it is linked to the GitHub repository. Click on the picture to be redirected to GitHub and easily copy the source code from there.

Generating a webhook

Go to the project settings page and scroll down to the webhook settings in the Automation section. Click on "Generate" to create a new webhook for the project.

image18

You can now send a POST request to the webhook whenever you want to start a scan for the project. The following examples show how to send the request.

Send Webhook

The following section explains how to trigger the webhook in the following software:

  • cURL
  • Heroku
  • TeamCity

cURL

To run the webhook manually, you can use the following cURL command. To start the scan from a shell script, integrate this command:

curl -X POST --data "" https://api.crashtest.cloud/webhook/SECRET_HASH

Heroku

You can set up Heroku to automatically call the webhook after a successful deployment:

heroku addons:create deployhooks:http --url=https://api.crashtest.cloud/webhook/SECRET_HASH

TeamCity

In TeamCity you can create a new build step where you run the webhook:

TeamCity Webhook Integration

Webhook Payload

It is possible to send a payload which contains authentication data. This data will be used to configure your project before starting the scan. Please note that previous user credentials will be overwritten and the credentials will be stored for the next scan. To send a webhook request with payload data you may use the following request:

curl --data '{
"system_authentication": {
"basic_auth": {
"username": "username",
"password": "password"
}
},
"application_authentication": [
{
"username": "username",
"password": "password",
"url": "example.com/login"
}
],
"parameter_authentication": [
{
"type": "HEADER",
"key": "Authentication",
"value": "Bearer 12345678"
}
]
}' -X POST https://api.crashtest.cloud/webhook/SECRET_HASH

Manual Login Flow

Let's assume that you have an REST API at https://example.com/api/v1 which uses JWT Tokens for authentication. The token is generated by a POST request to /login with the username 'username' and the password 'password'.

$ curl --data '{"username": "username", "password": "password"}' -X POST https://example.com/api/v1/login

{
"token_type": "Bearer",
"expires_in": 86400,
"access_token": "ABCDEF",
"refresh_token": "ABCDEF",
"concurrent_sessions": 1,
"max_current_sessions": 40,
}

You may use this to generate a script which logs you in before starting the security scan. The token generated by the login request is then used for the security scan.

ACCESS_TOKEN=`curl --data '{"username": "username", "password": "password"}' -X POST https://example.com/api/v1/login | jq -r '.access_token`
curl --data "{
\"parameter_authentication\": [
{
\"type\": \"HEADER\",
\"key\": \"Authentication\",
\"value\": \"Bearer $ACCESS_TOKEN\"
}
]
}" -X POST https://api.crashtest.cloud/webhook/SECRET_HASH

Responses

The following json responses inform you about the result of the webhook call:

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

Retrieve Scan Report using Webhook

You can not only start the scan using a webhook but also retrieve the report as JUnit XML format. The following script will start the scan for your project and periodically poll the status of the scan. When the scan is finished, the report will be downloaded to the file report.xml. For this script to run properly, you will need to have the following requirements installed: curl, jq

#!/usr/bin/env sh


# TODO: Set WEBHOOK to webhook ID (without URL)
WEBHOOK="aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa"


API_ENDPOINT="https://api.crashtest.cloud/webhook"

# Start Scan and get scan ID
SCAN_ID=`curl --silent -X POST --data "" $API_ENDPOINT/$WEBHOOK | jq .data.scanId`
echo "Started Scan for Webhook $WEBHOOK. Scan ID is $SCAN_ID."

# Refresh Scan status
STATUS="100"
while [[ $STATUS -le "101" ]]
do
echo "Scan Status currently is $STATUS (101 = Running)"
# Only poll every minute
sleep 60

# Refresh status
STATUS=`curl --silent $API_ENDPOINT/$WEBHOOK/scans/$SCAN_ID/status | jq .data.status.code`
done

echo "Scan finished with status $STATUS."

# Download Report
curl --silent $API_ENDPOINT/$WEBHOOK/scans/$SCAN_ID/report/junit -o report.xml
echo "Downloaded Report to report.xml"