Third-Party Scan REST API - v2
The Third-Party Scan REST API allows for single, or multiple components, to be scanned against a specific application and associated policies, generating an Application Composition Report.
Some possible use cases:
- Program analysis has already identified the data. The data will go through the policy engine and be shown in an Application Composition Report.
- Nexus IQ Server performs the program analysis. Nexus IQ Server will identify the data. Then go through the policy engine and be shown in an Application Composition Report.
This API uses the following REST resources:
- POST - to submit a list of components, allows to submit a list of components in CycloneDx format, to evaluate policies against an existing IQ application.
- GET - to get the result of the components submitted in with the POST resource.
For the API below is a step-by-step example using the HTTP client cURL, though any HTTP client tool could be used. In addition, we’ll reference other APIs such as the one required to obtain an application’s internal ID.
Step 1 - Get the Application ID
First, you will need to pick the application you want to evaluate your component against. This begins with obtaining the application’s public ID, which is used to retrieve the internal application ID.
The public ID can be found via the IQ Server GUI by navigating to the respective application and copying the application ID, which is located just below the application name.
This is done using the following GET REST resource from our application API:
GET /api/v2/applications?publicId={YourPublicId}
Using the cURL command, it would look like this:
curl -u admin:admin123 -X GET 'http://localhost:8070/api/v2/applications?publicId=MyApplicationID'
Information will be returned (unique to your application). This has been formatted for readability:
{ "applications": [ { "id": "4537e6fe68c24dd5ac83efd97d4fc2f4", "publicId": "MyApplicationID", "name": "MyApplication", "organizationId": "bb41817bd3e2403a8a52fe8bcd8fe25a", "contactUserName": "NewAppContact", "applicationTags": [ { "id": "9beee80c6fc148dfa51e8b0359ee4d4e", "tagId": "cfea8fa79df64283bd64e5b6b624ba48", "applicationId": "4bb67dcfc86344e3a483832f8c496419" } ] } ] }
From the information returned above, make a note of the id. This is the internal application ID.
Step 2 - Submit SBOM content for evaluation
The API allows valid SBOM files to be evaluated against IQ server policies. The SBOM (Software Bill-of-Materials) is a list of components of a piece of software, for this API in particular, we are going to use CycloneDX SBOM which consists in a lightweight software bill-of-material (SBOM) specification designed for use in application security contexts and supply chain component analysis. Please visit CycloneDX for more information about it in order to generate one.
Alright, by now you should have the SBOM, as well as the internal application ID and source. We’ll put this information together using the POST REST resource:
POST /api/v2/scan/applications/{applicationInternalId}/sources/{source}?stageId={stageId}
stageId param is optional, default value is build. Other allowed values include: develop, stage-release, release, and operate.
source is used to specify the source of the SBOM file or the tool used to create the SBOM.
Added to this will be an
SBOM XML formatted body where {version} is 1.4:
<bom xmlns="http://cyclonedx.org/schema/bom/{version}" serialNumber="urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79" version="1"> <components> <component type="library"> <publisher>Apache</publisher> <group>org.apache.tomcat</group> <name>tomcat-catalina</name> <version>9.0.14</version> <purl>pkg:maven/org.apache.tomcat/tomcat-catalina@9.0.14?type=jar</purl> </component> </components> </bom>
Supported versions and Compatiblity
IQ Release | Bom Specification | Vulnerability Specification | Supported Formats |
---|---|---|---|
77 | 1.1 | XML | |
78 | 1.0 | XML | |
81 | license element support | XML | |
114 | 1.2 | 1.0 | XML |
117 | 1.3 | 1.0 | XML |
134 | 1.4 | XML + JSON |
Support for CycloneDX vulnerability schema 1.0 XML extension is deprecated with bom specification 1.4 and you must use the vulnerabilities type included with version 1.4. (You could however still use it with previous bom specification versions)
Here is an example bom 1.4 XML file.
<?xml version="1.0" encoding="UTF-8"?> <bom xmlns="http://cyclonedx.org/schema/bom/1.4" serialNumber="urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79" version="1"> <metadata> <component type="application" bom-ref="acme-app"> <name>Acme Application</name> <version>9.1.1</version> </component> </metadata> <components> <component type="library"> <name>acme-library</name> <version>1.0.0</version> <hashes> <hash alg="SHA-1">9188560f22e0b73070d2efce670c74af2bdf30af</hash> <hash alg="SHA-256">d88bc4e70bfb34d18b5542136639acbb26a8ae2429aa1e47489332fb389cc964</hash> </hashes> <cpe>cpe:/a:acme:application:9.1.1</cpe> </component> <component type="library"> <group>com.fasterxml.jackson.core</group> <name>jackson-databind</name> <version>2.8.0</version> <licenses> <license> <id>Apache-2.0</id> </license> </licenses> <purl>pkg:maven/com.fasterxml.jackson.core/jackson-databind@2.8.0?type=jar</purl> </component> </components> <vulnerabilities> <vulnerability> <id>CVE-2018-7489</id> <source> <name>NVD</name> <url>https://nvd.nist.gov/vuln/detail/CVE-2019-9997</url> </source> <ratings> <rating> <source> <name>NVD</name> <url>https://nvd.nist.gov/vuln-metrics/cvss/v3-calculator?vector=AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H&version=3.0</url> </source> <score>9.8</score> <severity>critical</severity> <method>CVSSv3</method> <vector>AN/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H</vector> </rating> </ratings> <cwes> <cwe>184</cwe> <cwe>502</cwe> </cwes> <description>FasterXML jackson-databind before 2.7.9.3, 2.8.x before 2.8.11.1 and 2.9.x before 2.9.5 allows unauthenticated remote code execution because of an incomplete fix for the CVE-2017-7525 deserialization flaw. This is exploitable by sending maliciously crafted JSON input to the readValue method of the ObjectMapper, bypassing a blacklist that is ineffective if the c3p0 libraries are available in the classpath.</description> <recommendation>Upgrade com.fasterxml.jackson.core:jackson-databind to version 2.6.7.5, 2.8.11.1, 2.9.5 or higher.</recommendation> <advisories> <advisory> <title>GitHub Commit</title> <url>https://github.com/FasterXML/jackson-databind/commit/6799f8f10cc78e9af6d443ed6982d00a13f2e7d2</url> </advisory> </advisories> <created>2021-01-01T00:00:00.000Z</created> <published>2021-01-01T00:00:00.000Z</published> <updated>2021-01-01T00:00:00.000Z</updated> <analysis> <state>not_affected</state> <justification>code_not_reachable</justification> <responses> <response>will_not_fix</response> <response>update</response> </responses> <detail>An optional explanation of why the application is not affected by the vulnerable component.</detail> </analysis> <affects> <target> <ref>pkg:maven/com.fasterxml.jackson.core/jackson-databind@2.8.0?type=jar</ref> </target> </affects> </vulnerability> </vulnerabilities> <dependencies> <dependency ref="acme-app"> <dependency ref="pkg:maven/org.acme/web-framework@1.0.0?type=jar" /> <dependency ref="pkg:maven/org.acme/persistence@3.1.0?type=jar" /> </dependency> <dependency ref="pkg:maven/org.acme/web-framework@1.0.0?type=jar"> <dependency ref="pkg:maven/org.acme/common-util@3.0.0?type=jar" /> </dependency> <dependency ref="pkg:maven/org.acme/persistence@3.1.0?type=jar"> <dependency ref="pkg:maven/org.acme/common-util@3.0.0?type=jar" /> </dependency> <dependency ref="pkg:maven/org.acme/common-util@3.0.0?type=jar" /> </dependencies> </bom>
Example bom JSON (version 1.4) file content
{ "bomFormat": "CycloneDX", "specVersion": "1.4", "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79", "version": 1, "metadata": { "timestamp": "2022-02-21T17:20:41Z", "component": { "name": "Acme Application", "version": "9.1.1", "type": "application", "bom-ref": "acme-app" } }, "components": [ { "name": "acme-library", "version": "1.0.0", "hashes": [ { "alg": "SHA-1", "content": "9188560f22e0b73070d2efce670c74af2bdf30af" }, { "alg": "SHA-256", "content": "d88bc4e70bfb34d18b5542136639acbb26a8ae2429aa1e47489332fb389cc964" } ], "cpe": "cpe:/a:acme:application:9.1.1", "type": "library" }, { "group": "com.fasterxml.jackson.core", "name": "jackson-databind", "version": "2.8.0", "licenses": [ { "license": { "id": "Apache-2.0" } } ], "purl": "pkg:maven/com.fasterxml.jackson.core/jackson-databind@2.8.0?type=jar", "type": "library" } ], "dependencies": [ { "ref": "acme-app", "dependsOn": [ "pkg:maven/org.acme/web-framework@1.0.0?type=jar", "pkg:maven/org.acme/persistence@3.1.0?type=jar" ] }, { "ref": "pkg:maven/org.acme/web-framework@1.0.0?type=jar", "dependsOn": [ "pkg:maven/org.acme/common-util@3.0.0?type=jar" ] }, { "ref": "pkg:maven/org.acme/persistence@3.1.0?type=jar", "dependsOn": [ "pkg:maven/org.acme/common-util@3.0.0?type=jar" ] }, { "ref": "pkg:maven/org.acme/common-util@3.0.0?type=jar", "dependsOn": [] } ], "vulnerabilities": [ { "id": "CVE-2018-7489", "source": { "name": "NVD", "url": "https://nvd.nist.gov/vuln/detail/CVE-2019-9997" }, "ratings": [ { "source": { "name": "NVD", "url": "https://nvd.nist.gov/vuln-metrics/cvss/v3-calculator?vector=AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H&version=3.0" }, "score": 9.8, "severity": "critical", "method": "CVSSv3", "vector": "AN/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H" } ], "cwes": [ 184, 502 ], "description": "FasterXML jackson-databind before 2.7.9.3, 2.8.x before 2.8.11.1 and 2.9.x before 2.9.5 allows unauthenticated remote code execution because of an incomplete fix for the CVE-2017-7525 deserialization flaw. This is exploitable by sending maliciously crafted JSON input to the readValue method of the ObjectMapper, bypassing a blacklist that is ineffective if the c3p0 libraries are available in the classpath.", "recommendation": "Upgrade com.fasterxml.jackson.core:jackson-databind to version 2.6.7.5, 2.8.11.1, 2.9.5 or higher.", "advisories": [ { "title": "GitHub Commit", "url": "https://github.com/FasterXML/jackson-databind/commit/6799f8f10cc78e9af6d443ed6982d00a13f2e7d2" } ], "created": "2021-01-01T00:00:00Z", "published": "2021-01-01T00:00:00Z", "updated": "2021-01-01T00:00:00Z", "analysis": { "state": "not_affected", "justification": "code_not_reachable", "response": [ "will_not_fix", "update" ], "detail": "An optional explanation of why the application is not affected by the vulnerable component." }, "affects": [ { "ref": "pkg:maven/com.fasterxml.jackson.core/jackson-databind@2.8.0?type=jar" } ] } ] }
Note: In the unlikely case of the same component being found more than once in the bom, only the data of the first component will be processed/shown.
NEW IN RELEASE 81
When there is no Package URL available, a component can also be specified using the coordinates tags:
- <name> : mandatory (even when <purl> is set)
- <version> : mandatory (even when <purl> is set)
- <group>: optional
- <publisher>: optional
In addition each component can also include licenses data as shown in the example below.
<bom xmlns="http://cyclonedx.org/schema/bom/1.4" serialNumber="urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79" version="1"> <components> <component type="library"> <publisher>Apache</publisher> <group>org.apache.tomcat</group> <name>tomcat-catalina</name> <version>9.0.14</version> <licenses> <license> <id>Apache-2.0</id> </license> </licenses> <purl>pkg:maven/org.apache.tomcat/tomcat-catalina@9.0.14?type=jar</purl> </component> </components> </bom>
NEW IN RELEASE 83
When there is no Package URL available, a component can also be specified using its content hash (SHA-1) along with its < name> and <version> :
<bom serialNumber="urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79" version="1" xmlns="http://cyclonedx.org/schema/bom/1.4"> <components> <component type="library"> <name>tomcat-catalina</name> <version>9.0.16</version> <hashes> <hash alg="SHA-1">e6b1000b94e835ffd37f4c6dcbdad43f4b48a02a</hash> </hashes> </component> </components> </bom>
Together, this should look like this:
curl -u admin:admin123 -X POST -H "Content-Type: application/xml" -d '<bom xmlns="http://cyclonedx.org/schema/bom/1.4" serialNumber="urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79" version="1"> <components> <component type="library"> <publisher>Apache</publisher> <group>org.apache.tomcat</group> <name>tomcat-catalina</name> <version>9.0.14</version> <purl>pkg:maven/org.apache.tomcat/tomcat-catalina@9.0.14?type=jar</purl> </component> </components> </bom>' 'http://localhost:8070/api/v2/scan/applications/4537e6fe68c24dd5ac83efd97d4fc2f4/sources/cyclone'
A successful POST will result in JSON formatted data providing a confirmation that the evaluation was submitted.
{ "statusUrl": "api/v2/scan/applications/a20bc16e83944595a94c2e36c1cd228e/status/9cee2b6366fc4d328edc318eae46b2cb" }
NEW IN RELEASE 78
Step 3 - Checking Status URL to get scan result
After step 2, with the statusUrl result we get, it's possible to check the status of the scan, t his is done using the following GET REST resource from our application API:
GET /api/v2/scan/applications/{applicationInternalId}/status/{statusId}
Using the cURL command, it would look like this:
curl -u admin:admin123 -X GET 'http://localhost:8070/api/v2/scan/applications/a20bc16e83944595a94c2e36c1cd228e/status/9cee2b6366fc4d328edc318eae46b2cb'
A successful GET will result in JSON formatted data providing information related to the result of the scan; there are different scenarios:
When the report that’s being consulted is ready:
{ "policyAction": "None", "reportHtmlUrl": "http://localhost:8070/ui/links/application/my-app/report/95c4c14e", "isError": false, "componentsAffected": { "critical": 0, "severe": 0, "moderate": 0 }, "openPolicyViolations": { "critical": 0, "severe": 0, "moderate": 0 }, "grandfatheredPolicyViolations": 0 }
When the report that’s being consulted is ready and there are policy actions:
{ "policyAction": "Failure", "reportHtmlUrl": "http://localhost:8070/ui/links/application/my-app/report/95c4c14e", "isError": false, "componentsAffected": { "critical": 1, "severe": 0, "moderate": 0 }, "openPolicyViolations": { "critical": 2, "severe": 1, "moderate": 0 }, "grandfatheredPolicyViolations": 0 }
Available policyAction are None, Warning, and Failure
NEW IN RELEASE 84
The following fields were added to the scan status response:
- componentsAffected
- openPolicyViolations
- grandfatheredPolicyViolations
When the scan/report is not ready yet, the next message is returned with HTTP Status 404:
Report with status id a20bc16e83944595a94c2e36c1cd228e for application with id a20bc16e83944595a94c2e36c1cd228e is not ready.
When the scan does not exist in IQ, the next message is returned with HTTP Status 404:
Policy evaluation status with id a20bc16e83944595a94c2e36c1cd228e for public application id cyclone was not found.
When there was an error while doing the scan:
{ "isError": true, "errorMessage": “Unable to evaluate policy, the scan 123456783944595a94c2e36c1cd228e could not be processed.” }
NEW IN RELEASE 104
Additional report URLs (pdf, raw, embeddable) are now included in the formatted JSON data. All report URLs are now relative URLs.
{ "policyAction": "Failure", "reportHtmlUrl": "ui/links/application/my-app/report/95c4c14e", "reportPdfUrl": "ui/links/application/my-app/report/95c4c14e/pdf", "reportDataUrl": "api/v2/applications/my-app/reports/95c4c14e/raw", "embeddableReportHtmlUrl": "ui/links/application/my-app/report/95c4c14e/embeddable" "isError": false, "componentsAffected": { "critical": 1, "severe": 0, "moderate": 0 }, "openPolicyViolations": { "critical": 2, "severe": 1, "moderate": 0 }, "grandfatheredPolicyViolations": 0 }
NEW IN RELEASE 133
When CycloneDX sbom includes the dependency graph together with the parent component data in the metadata element, nexus IQ will enhance the results with dependency information and InnerSource insight data. For example:
<?xml version="1.0" encoding="UTF-8"?> <bom xmlns="http://cyclonedx.org/schema/bom/1.4" version="1"> <metadata> <component type="application" bom-ref="acme-app"> <name>Acme Application</name> <version>9.1.1</version> <purl>pkg:maven/org.acme/acme-app@9.1.1?type=jar</purl> </component> </metadata> <components> <component type="framework" bom-ref="pkg:maven/org.acme/web-framework@1.0.0?type=jar"> <group>org.acme</group> <name>web-framework</name> <version>1.0.0</version> <purl>pkg:maven/org.acme/web-framework@1.0.0?type=jar</purl> </component> <component type="library" bom-ref="pkg:maven/org.acme/persistence@3.1.0?type=jar"> <group>org.acme</group> <name>persistence</name> <version>3.1.0</version> <purl>pkg:maven/org.acme/persistence@3.1.0?type=jar</purl> </component> <component type="library" bom-ref="pkg:maven/org.acme/common-util@3.0.0?type=jar"> <group>org.acme</group> <name>common-util</name> <version>3.0.0</version> <purl>pkg:maven/org.acme/common-util@3.0.0?type=jar</purl> </component> </components> <dependencies> <dependency ref="acme-app"> <dependency ref="pkg:maven/org.acme/web-framework@1.0.0?type=jar"/> <dependency ref="pkg:maven/org.acme/persistence@3.1.0?type=jar"/> </dependency> <dependency ref="pkg:maven/org.acme/web-framework@1.0.0?type=jar"> <dependency ref="pkg:maven/org.acme/common-util@3.0.0?type=jar"/> </dependency> <dependency ref="pkg:maven/org.acme/persistence@3.1.0?type=jar"> <dependency ref="pkg:maven/org.acme/common-util@3.0.0?type=jar"/> </dependency> <dependency ref="pkg:maven/org.acme/common-util@3.0.0?type=jar"/> </dependencies> </bom>