AWS Lambda setup: create Lambda function to connect Snyk to Slack

AWS Lambda functions are used to connect Snyk to Slack because these functions are an inexpensive and efficient way of running code triggered by events, for example when there is a new Snyk vulnerability.

Note: If publishing the Lambda function through API Gateway, both must be configured in the same region. You can check this on the top right of the AWS Console.

Start by creating a zip file containing the code for the function and the necessary dependencies.

  1. Save these two code blocks as package.json and index.js

    1. package.json (modify to fit any other dependencies needed for your code, the dependencies needed are axios and crypto)

      {
        "name": "snyk-webhook-handler",
        "version": "1.0.0",
        "description": "Snyk to Slack Webhook Integration",
        "main": "index.js",
        "scripts": {
          "test": "echo \"Error: no test specified\" && exit 1"
        },
        "author": "",
        "license": "ISC",
        "dependencies": {
          "axios": "^1.1.3",
          "crypto": "^1.0.1"
        }
      }
    2. index.js

      const crypto = require('crypto')
      const axios = require('axios')
      
      let slackWebhookUrl = '<your_slackWebhookUrl_here>' // adjust
      
      //customised messaging to Slack with issue information, modify as needed
      async function messageSlack(
        message,
        snykProjectUrl,
        snykProjectName,
        snykIssuePackage,
        snykIssueUrl,
        snykIssueId,
        severity,
        snykIssuePriority
      ) {
        //strings modified to avoid Axios/Slack errors
        snykProjectUrl = snykProjectUrl.replace(/['"]+/g, '')
        snykProjectName = snykProjectName.replace(/['"]+/g, '')
        snykIssueUrl = snykIssueUrl.replace(/['"]+/g, '')
        snykIssueId = snykIssueId.replace(/['"]+/g, '')
        snykIssuePackage = snykIssuePackage.replace(/['"]+/g, '')
        severity = severity.replace(/['"]+/g, '')
      
        //construct message
        let payload = {
          text: `${message}`,
          blocks: [
            {
              type: 'header',
              text: {
                type: 'plain_text',
                text: `${message}`,
              },
            },
            {
              type: 'section',
              text: {
                type: 'mrkdwn',
                text: `Snyk has found a new vulnerability in the project:\n*<${snykProjectUrl}|${snykProjectName}>*`,
              },
            },
            {
              type: 'divider',
            },
            {
              type: 'section',
              fields: [
                {
                  type: 'mrkdwn',
                  text: `*Package name:*\n${snykIssuePackage}`,
                },
                {
                  type: 'mrkdwn',
                  text: `*Vulnerability:*\n<${snykIssueUrl}|${snykIssueId}>`,
                },
                {
                  type: 'mrkdwn',
                  text: `*Severity:*\n${severity}`,
                },
                {
                  type: 'mrkdwn',
                  text: `*Priority Score:*\n${snykIssuePriority}`,
                },
              ],
            },
            {
              type: 'actions',
              elements: [
                {
                  type: 'button',
                  text: {
                    type: 'plain_text',
                    text: 'View in Snyk',
                  },
                  style: 'primary',
                  url: snykProjectUrl,
                  value: 'browseUrl',
                },
              ],
            },
          ],
        }
      
        //send message
        const res = await axios.post(slackWebhookUrl, payload)
        const data = res.data
      }
      
      exports.handler = async (event) => {
        // Securing integrity of payload, this can be moved to another Lambda function and called seperately for authentication
        let response
      
        const {hmac_verification, severity_threshold} = process.env
        const hmac = crypto.createHmac('sha256', hmac_verification)
        const event_body = JSON.parse(event.body)