Webhook Integration for Serverless

  • Updated

IMPORTANT: This document assumes you already have an Organization within the Contrast UI with Serverless enabled: Contrast Serverless Application Security.

 

Objective

To provide steps to configure the Webhook integration for Contrast Serverless Application Security. 

 

Process

1. Getting Organization Authentication Details

Log in with Admin account for your serverless organization and get Organization UUID, API key and Authorization Header from the User Settings page.

Organization UUID: {orgUuid}
Organization API Key: {API-Key}
Admin User Authorization Header: {Authorization}

Your Keys

image-20220120-200245.png

 

2. Creating Serverless Generic Webhook

At the moment of writing this document, the UI work to create Serverless Generic Webhook was not ready. The only way to create a Serverless Generic Webhook is via API.

  • serverless_account_ids and serverless_rule_severities attributes in the Request body can be empty which means that this webhook will match any new vulnerability serverless event received.

  • Use the Authorization and API-Key header values obtained in the previous section.

Request

// POST http://<YourContrastURL>/Contrast/api/ng/{orgUuid}/webhooks

curl --request POST 'http://<YourContrastURL>/Contrast/api/ng/{orgUuid}/webhooks' \
--header 'Content-Type: application/json;charset=UTF-8' \
--header 'Authorization: {Authorization}' \
--header 'API-Key: {API-Key}' \
--data-raw '{
"name":"Serverless Generic Webhook",
"url":"https://ent3azpoyfw7b.x.pipedream.net",
"payload": "{\n \"severity\": $Severity,\n \"status\": $Status,\n \"scanId\": $ScanId,\n \"resourceId\": $ResourceId,\n \"resultFirstTimeFound\": $ResultFirstTimeFound,\n \"resultLastTimeSeen\": $ResultLastTimeSeen,\n \"resultId\": $ResultId,\n \"resultTitle\": $ResultTitle,\n \"resultCategory\": $ResultCategory,\n \"resultEvidence\": $ResultEvidence,\n \"resultImpact\": $ResultImpact,\n \"resultRemediation\": $ResultRemediation,\n \"resultDescription\": $ResultDescription,\n \"accountId\": $AccountId,\n \"accountName\": $AccountName,\n \"region\": $Region,\n \"provider\": $Provider\n}",
"use_html":true,
"send_failure_notification":true,
"all_applications":true,
"applications":[],
"product":"SERVERLESS",
"serverless_account_ids":["account-1"],
"serverless_rule_severities":["CRITICAL"],
"type":"GENERIC"
}'


Response
{
"success": true,
"messages": [
"Webhook configuration connected successfully"
]
}

 

3. Getting Serverless User Authentication Details

Request

// GET http://<YourContrastURL>/Contrast/api/ng/organizations/{orgUuid}/serverless/keys

curl --request GET 'http://<YourContrastURL>/Contrast/api/ng/organizations/{orgUuid}/serverless/keys' \
--header 'Content-Type: application/json' \
--header 'Authorization: {Authorization}' \
--header 'API-Key: {API-Key}'


Response
{
"success": true,
"messages": [
"Serverless service key loaded successfully"
],
"service_key": "HQNGP773Q5QA20I3",
"user_uid": "serverless_8d734fa9-289b-48fa-89df-035724dee5a4@ServerlessGenericWebhookNotifications"
}

 

4. Sending Serverless Vulnerability Events Requests

Request

// POST http://<YourContrastURL>/Contrast/integrations/v1.0/organizations/{orgUuid}/notifications/vulnerabilities

curl --request POST 'http://<YourContrastURL>/Contrast/integrations/v1.0/organizations/{orgUuid}/notifications/vulnerabilities' \
--header 'Content-Type: application/json' \
--header 'Authorization: {Authorization}' \
--header 'API-Key: {API-Key}' \
--data-raw '{
   "eventType": "NEW_RESULT",
   "sarifRun": {
       "tool": {
           "driver": {
               "name": "CloudEssence",
               "rules": [
                   {
                       "id": "LFI",
                       "name": "LFI",
                       "guid": "bf1c73ba-3d5a-4894-b880-1becaab566ad",
                       "messageStrings": {
                           "title": {
                               "text": "Local File Inclusion (LFI)"
                           }
                       }
                   }
               ],
               "taxa": [
                   {
                       "id": "Exploit",
                       "name": "Exploit",
                       "guid": "e0da8b7d-5b3f-4eac-ba57-bbb791ece6f0"
                   }
               ]
           }
       },
       "results": [
           {
               "ruleId": "LFI",
               "ruleIndex": 0,
               "rule": {
                   "guid": "bf1c73ba-3d5a-4894-b880-1becaab566ad"
               },
               "message": {
                   "id": "title"
               },
               "locations": [
                   {
                       "id": 0,
                       "message": {
                           "text": "The File Inclusion vulnerability allows an attacker to include a file, usually exploiting a '\''dynamic file inclusion'\'' mechanisms implemented in the target application. The vulnerability occurs due to the use of user-supplied input without proper validation. A successful attack can lead into reading the Function'\''s source code as well as other sensitive files in the environment."
                       }
                   }
               ],
               "relatedLocations": [
                   {
                       "id": 1,
                       "message": {
                           "text": "JSON"
                       },
                       "physicalLocation": {
                           "artifactLocation": {
                               "uri": "unknown"
                           },
                           "region": {
                               "message": {
                                   "text": "correctly permissive policy in json"
                               },
                               "snippet": {
                                   "rendered": {
                                       "text": "{\"correctly permissive\" : \"policy\"}"
                                   }
                               }
                           }
                       }
                   },
                   {
                       "id": 2,
                       "message": {
                           "text": "YAML"
                       },
                       "physicalLocation": {
                           "artifactLocation": {
                               "uri": "unknown"
                           },
                           "region": {
                               "message": {
                                   "text": "correctly permissive policy in yaml"
                               },
                               "snippet": {
                                   "rendered": {
                                       "text": "{\"correctly permissive\" : \"policy\"}"
                                   }
                               }
                           }
                       }
                   },
                   {
                       "id": 3,
                       "message": {
                           "text": "TERRAFORM"
                       },
                       "physicalLocation": {
                           "artifactLocation": {
                               "uri": "unknown"
                           },
                           "region": {
                               "message": {
                                   "text": "correctly permissive policy in terraform"
                               },
                               "snippet": {
                                   "rendered": {
                                       "text": "{\"correctly permissive\" : \"policy\"}"
                                   }
                               }
                           }
                       }
                   }
               ],
               "codeFlows": [
                   {
                       "message": {
                           "text": "cloudessence has identified evidence in the function logs (CWL) that indicates of was successfull exploit"
                       },
                       "threadFlows": [
                           {
                               "locations": [
                                   {
                                       "location": {
                                           "physicalLocation": {
                                               "artifactLocation": {
                                                   "uri": "unknown"
                                               },
                                               "region": {
                                                   "snippet": {
                                                       "rendered": {
                                                           "text": "payload: ../../../etc/passwd\nrequestId: 3fa6d034-242f-4aa6-b125-19a2d9bc9132\nlogGroup: /aws/lambda/DVSA-ADMIN-SHELL\nlogStream: 2021/07/16/[$LATEST]0ab88791946445889df3d95465a1f173"
                                                       }
                                                   }
                                               }
                                           }
                                       }
                                   }
                               ]
                           }
                       ]
                   }
               ],
               "guid": "a59e4ada-8899-45f1-bb68-a1595558a7fc",
               "provenance": {
                   "firstDetectionTimeUtc": "2021-07-16T16:13:51.419002Z",
                   "lastDetectionTimeUtc": "2021-07-16T16:14:53.420642Z"
               },
               "properties": {
                  "security-severity": 9.0,
                   "contrastSeverity": "MEDIUM",
                   "category": "EXPLOITS",
                   "status": "REPORTED",
                   "additionalExplanation": {
                       "recommendation": {
                           "text": "The most effective solution to eliminate file inclusion vulnerabilities is to avoid passing user-submitted input to any filesystem. If this is not possible the application can maintain an allow list of files, that may be included by the page, and then use an identifier (for example the index number) to access to the selected file. Any request containing an invalid identifier has to be rejected, in this way there is no attack surface for malicious users to manipulate the path.",
                           "properties": {
                               "title": "Remediation"
                           }
                       },
                       "impact": {
                           "text": "execute-api,ses,logs,cloudformation,cloudwatch,ec2,kms,iam,lambda,states,tag,xray",
                           "properties": {
                               "title": "Impact"
                           }
                       }
                   },
                   "additionalIdentificationInformation": {
                       "function": {
                           "text": "arn:aws:lambda:us-east-1:402181209224:function:DVSA-ADMIN-SHELL"
                       },
                       "accountId": {
                           "text": "402181209224"
                       },
                       "accountName": {
                           "text": "accountNameDemo"
                       },
                       "region": {
                           "text": "us-east-1"
                       },
                       "provider": {
                           "text": "aws"
                       },
                       "scanId": {
                           "text": "402181209224#0abb6825-060c-4627-ac77-742258cc335e"
                       }
                   },
                   "matching": {
                       "accountId": "account-1",
                       "severity": "CRITICAL"
                   }
               }
           }
       ]
   }
}'


Response
[
   {
       "requestUuid": "8bd35b15-b1ae-4231-9402-71524dc4b1cc",
       "resultGuid": "a59e4ada-8899-45f1-bb68-a1595558a7fc",
       "requestStatus": "IN_PROGRESS"
   }
]

 

5. Checking Serverless Vulnerability Events Request status

To check the status of the request, you can use the field requestUuid (8bd35b15-b1ae-4231-9402-71524dc4b1cc) from the Sending Serverless Vulnerability Events Requests section

Check request status

// GET 'http://<YourContrastURL>/Contrast/integrations/v1.0/organizations/{orgUuid}/notifications/requests/{requestUuid}'

curl --request GET 'http://<YourContrastURL>/Contrast/integrations/v1.0/organizations/{orgUuid}/notifications/requests/{requestUuid}' \
--header 'Content-Type: application/json' \
--header 'Authorization: {Authorization}' \
--header 'API-Key: {API-Key}'


Response
{
   "requestUuid": "8bd35b15-b1ae-4231-9402-71524dc4b1cc",
   "resultGuid": "a59e4ada-8899-45f1-bb68-a1595558a7fc",
   "requestStatus": "COMPLETED",
   "integrationStatuses": [
       {
           "integrationId": 7,
           "integrationType": "GENERIC",
           "status": "SUCCESS",
           "responseCode": 200,
           "resultGuid": "a59e4ada-8899-45f1-bb68-a1595558a7fc",
           "matchingCriteria": {
               "product": "SERVERLESS",
               "matchingConditions": {
                   "severity": [
                       "CRITICAL"
                   ],
                   "accountId": [
                       "account-1"
                   ]
               }
           }
       }
   ]
}

 

Was this article helpful?

0 out of 0 found this helpful

Have more questions? Submit a request