Using the Snyk API to get your vulnerabilities

Josh Emerson's avatar Josh Emerson
An illustration of a puzzle, with a piece containing the Snyk dog logo
Illustration by Lou Reade.

In this blog post, you will learn how to use the Snyk API to retrieve all the issues associated with a given project. There are several reasons you may find it valuable, notably pulling them into your reports and dashboards, giving management and developers visibility into their vulnerability status within the portals and workflows they’re already using.

Over the following steps, we will use the API to:

  • Fetch the list of organisations you have access to
  • Fetch all projects under an organisation
  • Fetch the list of issues for your projects

Prerequisites

To get started with the API, log in or sign up for an account, and grab your API key from https://snyk.io/account. You can learn about all the endpoints exposed by the API at https://snyk.docs.apiary.io.

If you haven’t already created some projects, you can do so by running snyk monitor via the Snyk command line tool, or you can add projects from various sources (such as GitHub, GitLab, and Heroku) via the website.

You’ll also want to copy your API key from https://snyk.io/account and use it everywhere you see <API_KEY> below.

Fetching organisations

The first step is to use the organisation’s endpoint at https://snyk.io/api/v1/orgs.

1
2
3
4
curl --include \
     --header "Content-Type: application/json; charset=utf-8" \
     --header "Authorization: token <API_KEY>" \
  'https://snyk.io/api/v1/orgs'

This will return a list of your organisations.

1
2
3
4
5
6
7
8
9
10
11
12
{
  "orgs": [
    {
      "name": "defaultOrg",
      "id": "689ce7f9-7943-4a71-b704-2ba575f01089"
    },
    {
      "name": "My Other Org",
      "id": "a04d9cbd-ae6e-44af-b573-0556b0ad4bd2"
    }
  ]
}

Fetching projects

Now take the ID of one that you wish to see project issues for and use it on the projects API endpoint at https://snyk.io/api/v1/org/<ORG_ID>/projects (replace <ORG_ID> with the id your organisation).

1
2
3
4
curl --include \
     --header "Content-Type: application/json" \
     --header "Authorization: token <API_KEY>" \
  'https://snyk.io/api/v1/org/<ORG_ID>/projects'

This will return a list of your projects.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
{
  "org": {
    "name": "defaultOrg",
    "id": "689ce7f9-7943-4a71-b704-2ba575f01089"
  },
  "projects": [
    {
      "name": "atokeneduser/goof",
      "id": "6d5813be-7e6d-4ab8-80c2-1e3e2a454545"
    },
    {
      "name": "atokeneduser/clojure",
      "id": "af127b96-6966-46c1-826b-2e79ac49bbd9"
    }
  ]
}

Fetching project issues

Now that we have a list of projects we can fetch issues for any project we are interested in by hitting the issues endpoint as shown below, replacing <PROJECT_ID> with the ID of the project you want to a see a list of issues for:

1
2
3
4
5
curl --include \
     --request POST \
     --header "Content-Type: application/json" \
     --header "Authorization: token <API_KEY>" \
  'https://snyk.io/api/v1/org/orgId/project/<PROJECT_ID>/issues'

This will return a JSON response including an issues object containing an array of vulnerabilities and (if licenses are enabled for your organisation) an array of license issues that were found in the project when the last snapshot was taken.

The project issues API endpoint also supports filtering by issue type (vulnerability or license issue), severity (high, medium or low) and by whether the issue was ignored or patched. If we only wanted to see high severity vulnerabilities that are not patched or ignored we could make the following request:

1
2
3
4
5
6
7
8
9
10
11
12
13
curl --include \
     --request POST \
     --header "Content-Type: application/json" \
     --header "Authorization: token <API_KEY>" \
     --data-binary '{
       "filters": {
        "severities": [ "high" ],
        "types": [ "vuln" ],
        "ignored": false,
        "patched": false
      }
    }' \
  'https://snyk.io/api/v1/org/orgId/project/<PROJECT_ID>/issues'

Now the response will not return any license issues, and will only show vulnerabilities that are high severity and have not been ignored or patched.

Using the response

Now that you have retrieved project issues, you will have a JSON payload as follows:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
{
  "ok": false,
  "issues": {
    "vulnerabilities": [
      {
        "id": "npm:ms:20170412",
        "url": "https://snyk.io/vuln/npm:ms:20170412",
        "title": "Regular Expression Denial of Service (ReDoS)",
        "type": "vuln",
        "description": "## Overview\n[`ms`](https://www.npmjs.com/package/ms) is a tiny millisecond conversion utility.\n\nAffected versions of this package are vulnerable to Regular Expression Denial of Service (ReDoS) due to an incomplete fix for previously reported vulnerability [npm:ms:20151024](https://snyk.io/vuln/npm:ms:20151024). The fix limited the length of accepted input string to 10,000 characters, and turned to be insufficient making it possible to block the event loop for 0.3 seconds (on a typical laptop) with a specially crafted string passed to `ms()` function.\n\n*Proof of concept*\n```js\nms = require('ms');\nms('1'.repeat(9998) + 'Q') // Takes about ~0.3s\n```\n\n**Note:** Snyk's patch for this vulnerability limits input length to 100 characters. This new limit was deemed to be a breaking change by the author.\nBased on user feedback, we believe the risk of breakage is _very_ low, while the value to your security is much greater, and therefore opted to still capture this change in a patch for earlier versions as well.  Whenever patching security issues, we always suggest to run tests on your code to validate that nothing has been broken.\n\nFor more information on `Regular Expression Denial of Service (ReDoS)` attacks, go to our [blog](https://snyk.io/blog/redos-and-catastrophic-backtracking/).\n\n## Disclosure Timeline\n- Feb 9th, 2017 - Reported the issue to package owner.\n- Feb 11th, 2017 - Issue acknowledged by package owner.\n- April 12th, 2017 - Fix PR opened by Snyk Security Team.\n- May 15th, 2017 - Vulnerability published.\n- May 16th, 2017 - Issue fixed and version `2.0.0` released.\n- May 21th, 2017 - Patches released for versions `>=0.7.1, <=1.0.0`.\n\n## Remediation\nUpgrade `ms` to version 2.0.0 or higher.\n\n## References\n- [GitHub PR](https://github.com/zeit/ms/pull/89)\n- [GitHub Commit](https://github.com/zeit/ms/pull/89/commits/305f2ddcd4eff7cc7c518aca6bb2b2d2daad8fef)\n",
        "from": [
          "mongoose@4.2.4",
          "mquery@1.6.3",
          "debug@2.2.0",
          "ms@0.7.1"
        ],
        "package": "ms",
        "version": "0.7.1",
        "severity": "low",
        "language": "js",
        "packageManager": "npm",
        "semver": {
          "unaffected": ">=2.0.0",
          "vulnerable": "<2.0.0"
        },
        "publicationTime": "2017-05-15T06:02:45.497Z",
        "disclosureTime": "2017-04-11T21:00:00.000Z",
        "isUpgradable": true,
        "isPatchable": true,
        "identifiers": {
          "CVE": [],
          "CWE": [
            "CWE-400"
          ],
          "ALTERNATIVE": [
            "SNYK-JS-MS-10509"
          ]
        },
        "credit": [
          "Snyk Security Research Team"
        ],
        "CVSSv3": "CVSS:3.0/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:N/A:L",
        "cvssScore": 3.7,
        "patches": [
          {
            "id": "patch:npm:ms:20170412:0",
            "urls": [
              "https://s3.amazonaws.com/snyk-rules-pre-repository/snapshots/develop/patches/npm/ms/20170412/ms_100.patch"
            ],
            "version": "=1.0.0",
            "comments": [],
            "modificationTime": "2017-05-16T10:12:18.990Z"
          },
          {
            "id": "patch:npm:ms:20170412:1",
            "urls": [
              "https://s3.amazonaws.com/snyk-rules-pre-repository/snapshots/develop/patches/npm/ms/20170412/ms_072-073.patch"
            ],
            "version": "=0.7.2 || =0.7.3",
            "comments": [],
            "modificationTime": "2017-05-16T10:12:18.990Z"
          },
          {
            "id": "patch:npm:ms:20170412:2",
            "urls": [
              "https://s3.amazonaws.com/snyk-rules-pre-repository/snapshots/develop/patches/npm/ms/20170412/ms_071.patch"
            ],
            "version": "=0.7.1",
            "comments": [],
            "modificationTime": "2017-05-16T10:12:18.990Z"
          }
        ],
        "isIgnored": true,
        "isPatched": false,
        "upgradePath": [
          "mongoose@4.10.2",
          "mquery@2.3.1",
          "debug@2.6.8",
          "ms@2.0.0"
        ]
      }
    ],
    "licenses": []
  },
  "dependencyCount": 250,
  "packageManager": "npm"
}

Lets say you wanted to display the vulnerability name, vulnerable package and the URL to learn more about each vulnerability. Using jq as an example, you could do the following:

1
2
3
4
5
curl --request POST \
   --header "Content-Type: application/json" \
   --header "Authorization: token <API_KEY>" \
  'https://snyk.io/api/v1/org/orgId/project/<PROJECT_ID>/issues' \
  | jq '"Vulnerability: \(.issues.vulnerabilities[].title) in \(.issues.vulnerabilities[].package)@\(.issues.vulnerabilities[].version) - \(.issues.vulnerabilities[].url)"'

And you’d get the following result:

1
Regular Expression Denial of Service (ReDoS) in ms@0.7.1 - https://snyk.io/vuln/npm:ms:20170412

The Reporting API

In a followup blog post, we will show how you can use the enterprise reporting API to go beyond what is possible via the project issues endpoint. If you want to chart issues over time, see time to resolution and have more powerfull filtering capabilities, get in touch by emailing enterprise@snyk.io to try out our reporting API.

Don't build security tools, build developer tools instead

January 09, 2018

Stop building security tools that think about dev, and start building dev tools that handle security.

Announcing Snyk for .NET, Go and PHP

December 21, 2017

Snyk has always been committed to making it easy to use open-source code without compromising security. Today, we're taking another leap forward and launching support for .NET, Go and PHP!

Subscribe to The Secure Developer Podcast

A podcast about security for developers, covering tools and best practices.

Find out more

Interested in web security?

Subscribe to our newsletter:

Get realtime updates and fixes for JavaScript, Ruby and Java vulnerabilities that affect your applications