DEV Community

Cover image for Implementing the JFrog Xray “Summary View” in Slack
Alex Hung for JFrog

Posted on

Implementing the JFrog Xray “Summary View” in Slack

Have you ever wanted to get your engineering teams real-time information about security issues happening during software development? As you may know, JFrog Xray already allows you to scan the entire composition of your binaries and enables you to send alerts to your teams using webhooks, but now with our new Slack integration we make it quite easy for entire channels to be updated in real time. The integration further allows teams to discuss new CVE's with developers on other teams as well. In order to make the JFrog Xray notifications super digestible in Slack, we built a whole new way to view your vulnerabilities and license compliance issues.

How It Works

The integration with Slack uses Jfrog Xray’s security and license compliance policies to trigger webhook events whenever a new violation is detected. Once configured, Xray sends a webhook event to our Slack integration which then transforms each issue in the event payload into UI cards that can be interacted with. In this blog, we’re going to talk about how we implemented one specific feature: the transformation of the payload to provide better usability to the end-user with our “Summary View” card.

Summary View - Why We Transform the Payload

When JFrog Xray scans your binaries and components, it uses a “watch” to tell it which repositories to scan artifacts from. The webhook will trigger a payload of vulnerability data based on how you setup your “policy” and set of rules in Xray. This payload will include every single vulnerability that has been introduced. We realized that when building a notifications app, the usability of this can be daunting. Imagine uploading a new artifact and realizing it has hundreds of vulnerabilities - getting hundreds of notifications in a Slack channel results in a lot of noise. This creates information overload and users can feel overwhelmed by the amount of messages in the channel resulting in them muting or ignoring the channel completely – which defeats the purpose of the information.

That is why we built what we call a “Summary view” of all the issues that come through the Xray payload. Christian Bongiorno (a senior software developer on the JFrog Partner team) created a transformed payload and we want to show you how it works.

Xray Notification Watches and Policies

Before Slack can receive messages from Xray, an Admin needs to assign your repositories inside Artifactory to a watch. This signifies that certain repositories should be monitored. You must also decide what policy and rules to apply that kickoff a notification to Slack. These rules can revolve around the level of severity you want to be notified of (low, medium, high), or if you want to be notified about specific license compliance issues.

Xray Process

Once you have setup policies and watches in Xray, you can then send notifications to Slack channels where your teams are monitoring these events.

How to Create Summary View Notifications in Slack

To create a notification, in the Slack app Home tab, click on the Create Notification button.

Slack App Home tab

Select Xray Violation from the dropdown menu.

Slack Create Notification modal - 1

In the Watch text box, type in the name of the Xray watch you want to use for this notification. This box will respond to the character you start typing and should show all the Xray watches on your JFrog platform.

Next, select the channel you want the notification sent to.

Slack Create Notification modal - 2

The next screen will ask you if you want to get notifications by individual CVE or by Summary View.

Getting Notifications by Component - Summary

By default, the format type View by Component (Summary) is selected for you. This format type groups all the issues for an artifact into categories based on severity (High, Medium, Low, Unknown). Each category will include up to 5 violations. To see the full list of issues, you can use the Open in platform button which opens Xray in your browser and takes you to the full list of Xray issues. This view helps your teams understand the extent to which a specific component might be affected by vulnerabilities.

Here is an example of the summary view message:

Xray summary message

Getting Notifications by Issue

Additionally, you can also get notification by each individual issue. This view is useful when you already have clean artifacts in production and just want to be notified anytime a new vulnerability pops up.

Here is an example of a individual security violation message:

Xray issue message

To avoid flooding the channel, our integration automatically switches to Summary view mode if the webhook event contains more than 40 individual issues. We found that users can digest the summary view much faster when there are more than 40 issues.

How We Built the Transformation Code

As we started making this integration available, we also found that many current JFrog Xray customers wanted to know how we transformed the Xray event data into a ‘Summary view’ card. We’ve made the template code available in the rest of this document.

First, this is what the default Xray payload looks like:

{
  "created": "2021-05-28T19:37:50.075822379Z",
  "top_severity": "Medium",
  "watch_name": "slack_watch_test",
  "policy_name": "slack",
  "issues": [
    {
      "severity": "Medium",
      "type": "security",
      "provider": "JFrog",
      "created": "2021-04-08T04:02:38.999Z",
      "summary": "A flaw was found in the Nosy driver in the Linux kernel. This issue allows a device to be inserted twice into a doubly-linked list, leading to a use-after-free when one of these devices is removed. The highest threat from this vulnerability is to confidentiality, integrity, as well as system availability. Versions before kernel 5.12-rc6 are affected",
      "description": "A flaw was found in the Nosy driver in the Linux kernel. This issue allows a device to be inserted twice into a doubly-linked list, leading to a use-after-free when one of these devices is removed. The highest threat from this vulnerability is to confidentiality, integrity, as well as system availability. Versions before kernel 5.12-rc6 are affected",
      "impacted_artifacts": [
        {
          "name": "manifest.json",
          "display_name": "artifactory-fluentd:1.11.2",
          "path": "default/integrations/artifactory-fluentd/1.11.2/",
          "pkg_type": "Docker",
          "sha256": "10fd87ba58132673ac65ee8c11a01510509f93846bdb5f20300ba5981aa75eb0",
          "sha1": "",
          "depth": 2,
          "parent_sha": "10fd87ba58132673ac65ee8c11a01510509f93846bdb5f20300ba5981aa75eb0",
          "infected_files": [
            {
              "name": "linux-libc-dev:4.19.132-1",
              "path": "",
              "sha256": "391e2df82c21b15e12cd8207d3257baf60b10c824c400e94bb1bd6128c131d55",
              "depth": 0,
              "parent_sha": "c5b1980eb2a26b21e083b2930ec5cae78f473a19d8fc6affbe6b71792fbf6ae2",
              "display_name": "debian:buster:linux-libc-dev:4.19.132-1",
              "pkg_type": "Debian"
            }
          ]
        }
      ],
      "cve": "CVE-2021-3483"
    }
  ]
}
Enter fullscreen mode Exit fullscreen mode

Then, when a Xray webhook event request arrives in our Slack integration, our transformer code extracts only the relevant information we want to use from the payload – then sorts the issues by severity.

const normalize = (violation) => violation.issues
  .map((issue) => issue.impacted_artifacts.map((artifact) => artifact.infected_files.map((file) => ({
    watch_name: violation.watch_name,
    severity: issue.severity,
    type: issue.type,
    pkg_type: artifact.pkg_type,
    summary: issue.summary,
    path: `${artifact.path.replace('default/', '')}`,
    file: file.name || artifact.name,
    description: issue.description,
    id: issue.cve || issue.summary,
  })))).flat(4);

const normalizedViolations = normalize(violation);
const reports = normalizedViolations.sort((a, b) => SEVERITY_MAPPING[a.severity] - SEVERITY_MAPPING[b.severity]);
Enter fullscreen mode Exit fullscreen mode

It then checks if the number of issues is greater than the 40 issue limit, and switches the format to the summary view.

if (messageFormat === ISSUE_MESSAGE_FORMAT && reports.length > SLACK_APP_MAX_ISSUES_PER_ENTRY) {
  messageFormat = SUMMARY_MESSAGE_FORMAT;
  forcedSummaryFormat = true;
}
Enter fullscreen mode Exit fullscreen mode

Afterwards it transforms the data into a Slack UI card using the corresponding format mapper module based on the format type.

const mapper = lookupFormatMapper(messageFormat);
return mapper(reports, jpdOrigin, policyOrWatchName, forcedSummaryFormat)?.map((r) => ({
  format,
  ...r,
}));
Enter fullscreen mode Exit fullscreen mode

In the Slack Integration, we use the Slack Web API to send the message to the targeted channel. We take this transformer code (the examples above) and make it available to the Slack platform. That is how we turn normal Xray webhook events into a “Summary View” card.

Our next goal will be to make the summary view adjustable – giving users more options and ways to build the summary. For now, we’ve made the code available on GitHub so you can also create understand how to create a custom summary from the payload that comes from JFrog Xray webhooks: https://github.com/jfrog/partner-integrations/tree/main/Slack/Sample

Follow the steps in the README.md to try this out for yourself!

To learn more about the JFrog App for Slack, visit us: https://jfrog.com/integration/slack/

Discussion (0)