API Rug Pull - The NIST NVD Database and API (Part 4 of 3)

Published: 2024-04-24
Last Updated: 2024-04-24 01:19:08 UTC
by Rob VandenBrink (Version: 1)
1 comment(s)

A while back I got an email from Perry, one of our readers who was having a problem using my cvescan script, which I covered in a 3 part story back in 2021:

The problem was simple, the script had just stopped working.  The NVD API version 1.0 had been retired in Dec 2023, and of course I had no idea.  A quick visit to their website got me the details of this change:

Anyway - this turned into a simple enough set of changes for my script, but some fundamental changes to the API itself.  Full docs for the API start here:

First, they moved from an open restful API to one that (they say) requires an API key (more on this later).  This takes care of change notifications in future, because you have to register to get a key.  Watch your spam folder, Outlook helpfully placed the email with the registration link in it in my Junk Email folder.

The original call in the NVD 1.0 API to collect CVE's for a specific product IOD (CPE) is:

$request = "https://services.nvd.nist.gov/rest/json/cves/1.0?modStartDate=" + $StartDate + "&cpeMatchString=" + $app.cpe

$CVEs = (invoke-webrequest $request | ConvertFrom-Json).result.CVE_items.cve.CVE_data_meta.id

Similarly, the NVD 1.0 API call to collect the metadtaa for a specific CVE:

$request = "https://services.nvd.nist.gov/rest/json/cve/1.0/" + $CVE.CVE

$cvemetadata = (invoke-webrequest $request) | convertfrom-json

In the version 2 API, let's construct an example call, looking for CVE's in Windows 10.  For a review of CPE's, check out the first 3 parts of this story.  I often "feed" CVEScan by collecting CPE's using nmap for instance.  Anyway, back to constructing the request:

$cpematchstring = "cpe:2.3:o:microsoft:windows_10:1607:*:*:*:*:*:*:*"

$request = "https://services.nvd.nist.gov/rest/json/cves/2.0?cpeName=" + $cpematchstring

Now let's make the call and look at the fields we get back:

(invoke-webrequest $request | ConvertFrom-Json) | gm

   TypeName: System.Management.Automation.PSCustomObject

Name            MemberType   Definition

----            ----------   ----------

Equals          Method       bool Equals(System.Object obj)

GetHashCode     Method       int GetHashCode()

GetType         Method       type GetType()

ToString        Method       string ToString()

format          NoteProperty string format=NVD_CVE

resultsPerPage  NoteProperty int resultsPerPage=2000

startIndex      NoteProperty int startIndex=0

timestamp       NoteProperty string timestamp=2024-04-23T17:40:15.370

totalResults    NoteProperty int totalResults=2574

version         NoteProperty string version=2.0

vulnerabilities NoteProperty Object[] vulnerabilities=System.Object[]

Now let's look at the vulnerability list, picking just a random item in the list:

$v = (invoke-webrequest $request | ConvertFrom-Json).vulnerabilities


id               : CVE-2016-0170

sourceIdentifier : secure@microsoft.com

published        : 2016-05-11T01:59:10.027

lastModified     : 2018-10-12T22:11:24.817

vulnStatus       : Modified

descriptions     : {@{lang=en; value=GDI in Microsoft Windows Vista SP2, Windows Server 2008 SP2 and R2 SP1, Windows 7

                   SP1, Windows 8.1, Windows Server 2012 Gold and R2, Windows RT 8.1, and Windows 10 Gold and 1511

                   allows remote attackers to execute arbitrary code via a crafted document, aka "Windows Graphics

                   Component RCE Vulnerability."}, @{lang=es; value=GDI en Microsoft Windows Vista SP2, Windows Server

                   2008 SP2 y R2 SP1, Windows 7 SP1, Windows 8.1, Windows Server 2012 Gold y R2, Windows RT 8.1 y

                   Windows 10 Gold y 1511 permite a atacantes remotos ejecutar c??digo arbitrario a trav??s de un

                   documento manipulado, tambi??n conocido como "Windows Graphics Component RCE Vulnerability".}}

metrics          : @{cvssMetricV30=System.Object[]; cvssMetricV2=System.Object[]}

weaknesses       : {@{source=nvd@nist.gov; type=Primary; description=System.Object[]}}

configurations   : {@{nodes=System.Object[]}}

references       : {@{url=http://packetstormsecurity.com/files/137096/Microsoft-Windows-gdi32.dll-ExtEscape-Buffer-Over

                   flow.html; source=secure@microsoft.com}, @{url=http://www.securityfocus.com/bid/89864;

                   source=secure@microsoft.com}, @{url=http://www.securitytracker.com/id/1035823;




There's no need for a second call, all the NVD metadata is in the returned data for that first call!  You can just keep parsing as deep as you want until you get the exact fields that you want!  For instance, if we just want the CVE list:

$cvelist =  $v.id





... and so on

Or if you wanted the CVE list and the last modified date:

$datelist =  (invoke-webrequest $request | ConvertFrom-Json).vulnerabilities.cve | select id,lastModified


id             lastModified

--             ------------

CVE-2013-3900  2022-11-02T15:15:43.850

CVE-2015-6184  2018-10-12T22:10:41.470

CVE-2016-0088  2018-10-12T22:11:00.707

CVE-2016-0089  2018-10-12T22:11:00.910

.. and so on

Sticking with our favourite item lucky 7, the description would be:


GDI in Microsoft Windows Vista SP2, Windows Server 2008 SP2 and R2 SP1, Windows 7 SP1, Windows 8.1, Windows Server 2012 Gold and R2, Windows RT 8.1, and Windows 10 Gold and 1511 allows remote attackers to execute arbitrary code via a crafted document, aka "Windows Graphics Component RCE Vulnerability."

To get exploitability and import scores for both version 2 and version 3 of the CVSS Metric:


ource                  : nvd@nist.gov

type                    : Primary

cvssData                : @{version=2.0; vectorString=AV:N/AC:M/Au:N/C:C/I:C/A:C; accessVector=NETWORK;

                          accessComplexity=MEDIUM; authentication=NONE; confidentialityImpact=COMPLETE;

                          integrityImpact=COMPLETE; availabilityImpact=COMPLETE; baseScore=9.3}

baseSeverity            : HIGH

exploitabilityScore     : 8.6

impactScore             : 10.0

acInsufInfo             : False

obtainAllPrivilege      : False

obtainUserPrivilege     : False

obtainOtherPrivilege    : False

userInteractionRequired : True






And for v3:


source              : nvd@nist.gov

type                : Primary

cvssData            : @{version=3.0; vectorString=CVSS:3.0/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H; attackVector=NETWORK;

                      attackComplexity=LOW; privilegesRequired=NONE; userInteraction=REQUIRED; scope=UNCHANGED;

                      confidentialityImpact=HIGH; integrityImpact=HIGH; availabilityImpact=HIGH; baseScore=8.8;


exploitabilityScore : 2.8

impactScore         : 5.9








version               : 3.0

vectorString          : CVSS:3.0/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H

attackVector          : NETWORK

attackComplexity      : LOW

privilegesRequired    : NONE

userInteraction       : REQUIRED

scope                 : UNCHANGED

confidentialityImpact : HIGH

integrityImpact       : HIGH

availabilityImpact    : HIGH

baseScore             : 8.8

baseSeverity          : HIGH




Going back to collect the URL references:

$v[7].cve.references | fl


url    : http://packetstormsecurity.com/files/137096/Microsoft-Windows-gdi32.dll-ExtEscape-Buffer-Overflow.html

source : secure@microsoft.com

url    : http://www.securityfocus.com/bid/89864

source : secure@microsoft.com

url    : http://www.securitytracker.com/id/1035823

source : secure@microsoft.com

url    : https://docs.microsoft.com/en-us/security-updates/securitybulletins/2016/ms16-055

source : secure@microsoft.com

So, for just the URLs:






The API key? So far I haven't needed it.  This may just be a way of the NVD folks getting a list of the developers that use their API (with email addresses), so that they can tell us in advance when API 2.1 or 3.0 is about to be released(?)  If it is, I'm 100% OK with that, I WANT to know in advance if someone else is going to break my code!

As always, I'll update my cvescan script in the next few days to match the new API, you can find it in my github then at https://github.com/robvandenbrink

If you have used external APIs in your code, then had the API unexpectedly change on you and bite you, please use our comment form and share the details (if your NDA permits?)

Rob VandenBrink

1 comment(s)


It feels like I'm somebody just to get mentioned in Rob's post. I am looking forward to using this tool at an undisclosed location. ;-)

Diary Archives