diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 4cda58ef..de5d3a47 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -36,13 +36,9 @@ jobs: for distro in alpine centos debian; do docker buildx imagetools inspect localhost:5000/match-coverage/$distro:latest done - - run: | - echo Downloading a pinned Grype DB for testing... - mkdir -p grype-db/3 - curl -sL https://toolbox-data.anchore.io/grype/databases/vulnerability-db_v3_2021-09-10T08:18:17Z.tar.gz | tar zxf - -C grype-db/3 - run: npm ci - run: npm audit --production - - run: GRYPE_DB_AUTO_UPDATE=false GRYPE_DB_CACHE_DIR=./grype-db npm test + - run: npm test functional: runs-on: ubuntu-latest diff --git a/.grype.yaml b/.grype.yaml new file mode 100644 index 00000000..3615dcc6 --- /dev/null +++ b/.grype.yaml @@ -0,0 +1,2 @@ +ignore: + - vulnerability: CVE-2021-32804 diff --git a/README.md b/README.md index f318516a..82a2cd88 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ :zap: _Find threats in files or containers at lightning speed_ :zap: -This is a GitHub Action for invoking the [grype](https://github.com/anchore/grype) scanner and returning the vulnerabilities found, +This is a GitHub Action for invoking the [Grype](https://github.com/anchore/grype) scanner and returning the vulnerabilities found, and optionally fail if a vulnerability is found with a configurable severity level. Use this in your workflows to quickly verify files or containers' content after a build and before pushing, allowing PRs, or deploying updates. @@ -111,7 +111,7 @@ The only required key is `image` or `path`; all the other keys are optional. The | Output Name | Description | Type | | ----------- | ----------------------------- | ------ | -| sarif | Path to the SARIF report file | string | +| `sarif` | Path to the SARIF report file | string | ### Example Workflows @@ -165,6 +165,12 @@ Optionally, you can add a step to inspect the SARIF report produced: run: cat ${{ steps.scan.outputs.sarif }} ``` +## Additional configuration + +You may add a `.grype.yaml` file at your repository root +for more [Grype configuration](https://github.com/anchore/grype#configuration) +such as [ignoring certain matches](https://github.com/anchore/grype#specifying-matches-to-ignore). + ## Contributing We love contributions, feedback, and bug reports. For issues with the invocation of this action, file [issues](https://github.com/anchore/scan-action/issues) in this repository. @@ -175,10 +181,7 @@ For contributing, see [Contributing](CONTRIBUTING.rst). For documentation on Grype itself, including other output capabilities, see the [grype project](https://github.com/anchore/grype) -Connect with the community directly on [slack](https://anchore.com/slack). These channels from Anchore's toolbox project are ideal for engaging development of help-related discussions: - -- grype-dev -- grype-help +Connect with the community directly on [slack](https://anchore.com/slack). [test]: https://github.com/anchore/scan-action [test-img]: https://github.com/anchore/scan-action/workflows/Tests/badge.svg diff --git a/dist/index.js b/dist/index.js index a9b75e7e..327fc629 100644 --- a/dist/index.js +++ b/dist/index.js @@ -12,7 +12,7 @@ const fs = __webpack_require__(747); const stream = __webpack_require__(413); const grypeBinary = "grype"; -const grypeVersion = "0.17.0"; +const grypeVersion = "0.22.0"; // sarif code function convert_severity_to_acs_level(input_severity, severity_cutoff_param) { @@ -534,8 +534,13 @@ async function runScan({ core.debug(cmdOutput); } - let grypeVulnerabilities = JSON.parse(cmdOutput); - + let grypeVulnerabilities; + try { + grypeVulnerabilities = JSON.parse(cmdOutput); + } catch (e) { + core.error(`Unable to parse grype output: ${e}`); + core.error(cmdOutput); + } if (acsReportEnable) { try { const serifOut = sarifGrypeGeneration( diff --git a/index.js b/index.js index d1080e09..6d4142c4 100644 --- a/index.js +++ b/index.js @@ -5,7 +5,7 @@ const fs = require("fs"); const stream = require("stream"); const grypeBinary = "grype"; -const grypeVersion = "0.17.0"; +const grypeVersion = "0.22.0"; // sarif code function convert_severity_to_acs_level(input_severity, severity_cutoff_param) { @@ -527,8 +527,13 @@ async function runScan({ core.debug(cmdOutput); } - let grypeVulnerabilities = JSON.parse(cmdOutput); - + let grypeVulnerabilities; + try { + grypeVulnerabilities = JSON.parse(cmdOutput); + } catch (e) { + core.error(`Unable to parse grype output: ${e}`); + core.error(cmdOutput); + } if (acsReportEnable) { try { const serifOut = sarifGrypeGeneration( diff --git a/package.json b/package.json index 20c43421..ba597c81 100644 --- a/package.json +++ b/package.json @@ -9,8 +9,9 @@ }, "scripts": { "lint": "eslint index.js", - "test": "eslint index.js && jest", - "update-snapshots": "eslint index.js && jest --updateSnapshot", + "test": "eslint index.js && npm run download-pinned-grype-db && GRYPE_DB_AUTO_UPDATE=false GRYPE_DB_CACHE_DIR=./grype-db jest", + "update-snapshots": "eslint index.js && npm run download-pinned-grype-db && GRYPE_DB_AUTO_UPDATE=false GRYPE_DB_CACHE_DIR=./grype-db jest --updateSnapshot", + "download-pinned-grype-db": "mkdir -p grype-db/3 && curl -sL https://toolbox-data.anchore.io/grype/databases/vulnerability-db_v3_2021-09-10T08:18:17Z.tar.gz | tar zxf - -C grype-db/3", "build": "ncc build ./index.js", "precommit": "pretty-quick --staged && npm run build && git add dist/", "prettier": "prettier -w index.js" diff --git a/tests/__snapshots__/sarif_output.test.js.snap b/tests/__snapshots__/sarif_output.test.js.snap index 7b8da351..df44cd1d 100644 --- a/tests/__snapshots__/sarif_output.test.js.snap +++ b/tests/__snapshots__/sarif_output.test.js.snap @@ -817,7 +817,7 @@ Object { ], "tool": Object { "driver": Object { - "dottedQuadFileVersion": "0.17.0.0", + "dottedQuadFileVersion": "0.22.0.0", "fullName": "Anchore Container Vulnerability Report (T0)", "name": "Anchore Container Vulnerability Report (T0)", "rules": Array [ @@ -1322,8 +1322,8 @@ Link: [CVE-2020-25708](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-25 }, }, ], - "semanticVersion": "0.17.0", - "version": "0.17.0", + "semanticVersion": "0.22.0", + "version": "0.22.0", }, }, }, @@ -1549,7 +1549,7 @@ Object { ], "tool": Object { "driver": Object { - "dottedQuadFileVersion": "0.17.0.0", + "dottedQuadFileVersion": "0.22.0.0", "fullName": "Anchore Container Vulnerability Report (T0)", "name": "Anchore Container Vulnerability Report (T0)", "rules": Array [ @@ -1679,8 +1679,8 @@ Link: [GHSA-pq64-v7f5-gqh8](https://github.com/advisories/GHSA-pq64-v7f5-gqh8)", }, }, ], - "semanticVersion": "0.17.0", - "version": "0.17.0", + "semanticVersion": "0.22.0", + "version": "0.22.0", }, }, }, @@ -1703,6 +1703,46 @@ Object { }, ], "results": Array [ + Object { + "analysisTarget": Object { + "uri": "tests/fixtures/npm-project/package-lock.json", + }, + "baselineState": "unchanged", + "level": "error", + "locations": Array [ + Object { + "logicalLocations": Array [ + Object { + "fullyQualifiedName": "dockerfile", + }, + ], + "physicalLocation": Object { + "artifactLocation": Object { + "uri": "tests/fixtures/npm-project/package-lock.json", + }, + "region": Object { + "byteLength": 1, + "byteOffset": 1, + "endColumn": 1, + "endLine": 1, + "startColumn": 1, + "startLine": 1, + }, + }, + }, + ], + "message": Object { + "id": "default", + "text": "The path tests/fixtures/npm-project/package-lock.json reports tar at version 6.1.0 which would result in a vulnerable (npm) package installed", + }, + "ruleId": "ANCHOREVULN_CVE-2021-32803_npm_tar_6.1.0", + "ruleIndex": 0, + "suppressions": Array [ + Object { + "kind": "external", + }, + ], + }, Object { "analysisTarget": Object { "uri": "tests/fixtures/npm-project/package-lock.json", @@ -1906,10 +1946,35 @@ Object { ], "tool": Object { "driver": Object { - "dottedQuadFileVersion": "0.17.0.0", + "dottedQuadFileVersion": "0.22.0.0", "fullName": "Anchore Container Vulnerability Report (T0)", "name": "Anchore Container Vulnerability Report (T0)", "rules": Array [ + Object { + "fullDescription": Object { + "text": "The npm package \\"tar\\" (aka node-tar) before versions 6.1.2, 5.0.7, 4.4.15, and 3.2.3 has an arbitrary File Creation/Overwrite vulnerability via insufficient symlink protection. \`node-tar\` aims to guarantee that any file whose location would be modified by a symbolic link is not extracted. This is, in part, achieved by ensuring that extracted directories are not symlinks. Additionally, in order to prevent unnecessary \`stat\` calls to determine whether a given path is a directory, paths are cached when directories are created. This logic was insufficient when extracting tar files that contained both a directory and a symlink with the same name as the directory. This order of operations resulted in the directory being created and added to the \`node-tar\` directory cache. When a directory is present in the directory cache, subsequent calls to mkdir for that directory are skipped. However, this is also where \`node-tar\` checks for symlinks occur. By first creating a directory, and then replacing that directory with a symlink, it was thus possible to bypass \`node-tar\` symlink checks on directories, essentially allowing an untrusted tar file to symlink into an arbitrary location and subsequently extracting arbitrary files into that location, thus allowing arbitrary file creation and overwrite. This issue was addressed in releases 3.2.3, 4.4.15, 5.0.7 and 6.1.2.", + }, + "help": Object { + "markdown": "**Vulnerability CVE-2021-32803** +| Severity | Package | Version | Fix Version | Type | Location | Data Namespace | Link | +| --- | --- | --- | --- | --- | --- | --- | --- | +|High|tar|6.1.0|none|npm|tests/fixtures/npm-project/package-lock.json|unknown|[CVE-2021-32803](https://nvd.nist.gov/vuln/detail/CVE-2021-32803)| +", + "text": "Vulnerability CVE-2021-32803 +Severity: High +Package: tar +Version: 6.1.0 +Fix Version: none +Type: npm +Location: tests/fixtures/npm-project/package-lock.json +Data Namespace: unknown +Link: [CVE-2021-32803](https://nvd.nist.gov/vuln/detail/CVE-2021-32803)", + }, + "id": "ANCHOREVULN_CVE-2021-32803_npm_tar_6.1.0", + "shortDescription": Object { + "text": "CVE-2021-32803 High vulnerability for tar package", + }, + }, Object { "fullDescription": Object { "text": "Arbitrary File Creation/Overwrite due to insufficient absolute path sanitization", @@ -2036,8 +2101,8 @@ Link: [GHSA-r628-mhmh-qjhw](https://github.com/advisories/GHSA-r628-mhmh-qjhw)", }, }, ], - "semanticVersion": "0.17.0", - "version": "0.17.0", + "semanticVersion": "0.22.0", + "version": "0.22.0", }, }, }, @@ -2060,6 +2125,46 @@ Object { }, ], "results": Array [ + Object { + "analysisTarget": Object { + "uri": "tests/fixtures/yarn-project/yarn.lock", + }, + "baselineState": "unchanged", + "level": "error", + "locations": Array [ + Object { + "logicalLocations": Array [ + Object { + "fullyQualifiedName": "dockerfile", + }, + ], + "physicalLocation": Object { + "artifactLocation": Object { + "uri": "tests/fixtures/yarn-project/yarn.lock", + }, + "region": Object { + "byteLength": 1, + "byteOffset": 1, + "endColumn": 1, + "endLine": 1, + "startColumn": 1, + "startLine": 1, + }, + }, + }, + ], + "message": Object { + "id": "default", + "text": "The path tests/fixtures/yarn-project/yarn.lock reports trim at version 0.0.2 which would result in a vulnerable (npm) package installed", + }, + "ruleId": "ANCHOREVULN_CVE-2020-7753_npm_trim_0.0.2", + "ruleIndex": 0, + "suppressions": Array [ + Object { + "kind": "external", + }, + ], + }, Object { "analysisTarget": Object { "uri": "tests/fixtures/yarn-project/yarn.lock", @@ -2103,10 +2208,35 @@ Object { ], "tool": Object { "driver": Object { - "dottedQuadFileVersion": "0.17.0.0", + "dottedQuadFileVersion": "0.22.0.0", "fullName": "Anchore Container Vulnerability Report (T0)", "name": "Anchore Container Vulnerability Report (T0)", "rules": Array [ + Object { + "fullDescription": Object { + "text": "All versions of package trim are vulnerable to Regular Expression Denial of Service (ReDoS) via trim().", + }, + "help": Object { + "markdown": "**Vulnerability CVE-2020-7753** +| Severity | Package | Version | Fix Version | Type | Location | Data Namespace | Link | +| --- | --- | --- | --- | --- | --- | --- | --- | +|High|trim|0.0.2|none|npm|tests/fixtures/yarn-project/yarn.lock|unknown|[CVE-2020-7753](https://nvd.nist.gov/vuln/detail/CVE-2020-7753)| +", + "text": "Vulnerability CVE-2020-7753 +Severity: High +Package: trim +Version: 0.0.2 +Fix Version: none +Type: npm +Location: tests/fixtures/yarn-project/yarn.lock +Data Namespace: unknown +Link: [CVE-2020-7753](https://nvd.nist.gov/vuln/detail/CVE-2020-7753)", + }, + "id": "ANCHOREVULN_CVE-2020-7753_npm_trim_0.0.2", + "shortDescription": Object { + "text": "CVE-2020-7753 High vulnerability for trim package", + }, + }, Object { "fullDescription": Object { "text": "Regular Expression Denial of Service in trim", @@ -2133,8 +2263,8 @@ Link: [GHSA-w5p7-h5w8-2hfq](https://github.com/advisories/GHSA-w5p7-h5w8-2hfq)", }, }, ], - "semanticVersion": "0.17.0", - "version": "0.17.0", + "semanticVersion": "0.22.0", + "version": "0.22.0", }, }, }, diff --git a/tests/sarif_output.test.js b/tests/sarif_output.test.js index 2ebfcd03..11529252 100644 --- a/tests/sarif_output.test.js +++ b/tests/sarif_output.test.js @@ -7,10 +7,10 @@ jest.setTimeout(30000); const testSource = async (source, vulnerabilities) => { if (fs.existsSync("./vulnerabilities.json")) { - fs.rmSync("./vulnerabilities.json"); + fs.unlinkSync("./vulnerabilities.json"); } if (fs.existsSync("./results.sarif")) { - fs.rmSync("./results.sarif"); + fs.unlinkSync("./results.sarif"); } const out = await runScan({