From 5d9700f752c59084887796f0d63b24d96f5c6c80 Mon Sep 17 00:00:00 2001 From: Konstantin Yegupov Date: Wed, 21 Aug 2019 09:13:32 +0100 Subject: [PATCH] Added tests --- src/cli/commands/test/index.ts | 4 +- src/lib/snyk-test/run-test.ts | 2 +- test/acceptance/cli.acceptance.test.ts | 65 ++- test/acceptance/fake-server.ts | 17 +- .../inspect-result.json | 41 ++ .../pip-app-transitive-vuln/requirements.txt | 1 + .../response-with-remediation.json | 490 ++++++++++++++++++ 7 files changed, 608 insertions(+), 12 deletions(-) create mode 100644 test/acceptance/workspaces/pip-app-transitive-vuln/inspect-result.json create mode 100644 test/acceptance/workspaces/pip-app-transitive-vuln/requirements.txt create mode 100644 test/acceptance/workspaces/pip-app-transitive-vuln/response-with-remediation.json diff --git a/src/cli/commands/test/index.ts b/src/cli/commands/test/index.ts index 6e08751f65..9f7a56d4b7 100644 --- a/src/cli/commands/test/index.ts +++ b/src/cli/commands/test/index.ts @@ -143,7 +143,9 @@ async function test(...args: MethodArgs): Promise { throw err; } - const pinningSupported = (await isFeatureFlagSupportedForOrg('pythonPinning')).ok; + const pinningSupported = + results.find((r) => (r as LegacyVulnApiResult).packageManager === 'pip') && + (await isFeatureFlagSupportedForOrg('pythonPinning')).ok; let response = results .map((unused, i) => { diff --git a/src/lib/snyk-test/run-test.ts b/src/lib/snyk-test/run-test.ts index 86cd0d8521..b71fcb8cbb 100644 --- a/src/lib/snyk-test/run-test.ts +++ b/src/lib/snyk-test/run-test.ts @@ -1,5 +1,5 @@ import * as _ from 'lodash'; -import fs = require('then-fs'); +import * as fs from 'fs'; import pathUtil = require('path'); import moduleToObject = require('snyk-module'); import * as depGraphLib from '@snyk/dep-graph'; diff --git a/test/acceptance/cli.acceptance.test.ts b/test/acceptance/cli.acceptance.test.ts index de26c2a082..76f9665e0c 100644 --- a/test/acceptance/cli.acceptance.test.ts +++ b/test/acceptance/cli.acceptance.test.ts @@ -32,8 +32,11 @@ const after = tap.runOnly ? only : test; // Should be after `process.env` setup. import * as plugins from '../../src/lib/plugins'; import { legacyPlugin as pluginApi } from '@snyk/cli-interface'; -import { AuthFailedError } from '../../src/lib/errors/authentication-failed-error'; -import { InternalServerError } from '../../src/lib/errors'; +import { fail } from 'assert'; + +function loadJson(filename: string) { + return JSON.parse(fs.readFileSync(filename, 'utf-8')) +} // @later: remove this config stuff. // Was copied straight from ../src/cli-server.js @@ -1224,7 +1227,10 @@ test('`test pip-app --file=requirements.txt`', async (t) => { await cli.test('pip-app', { file: 'requirements.txt', }); - const req = server.popRequest(); + let req = server.popRequest(); + t.equal(req.method, 'GET', 'makes GET request'); + t.match(req.url, 'cli-config/feature-flags/pythonPinning', 'to correct url'); + req = server.popRequest(); t.equal(req.method, 'POST', 'makes POST request'); t.equal(req.headers['x-snyk-cli-version'], versionNumber, 'sends version number'); t.match(req.url, '/test-dep-graph', 'posts to correct url'); @@ -1266,7 +1272,10 @@ test('`test pipenv-app --file=Pipfile`', async (t) => { await cli.test('pipenv-app', { file: 'Pipfile', }); - const req = server.popRequest(); + let req = server.popRequest(); + t.equal(req.method, 'GET', 'makes GET request'); + t.match(req.url, 'cli-config/feature-flags/pythonPinning', 'to correct url'); + req = server.popRequest(); t.equal(req.method, 'POST', 'makes POST request'); t.equal(req.headers['x-snyk-cli-version'], versionNumber, 'sends version number'); t.match(req.url, '/test-dep-graph', 'posts to correct url'); @@ -1284,6 +1293,54 @@ test('`test pipenv-app --file=Pipfile`', async (t) => { }], 'calls python plugin'); }); +test('`test pip-app-transitive-vuln --file=requirements.txt`', async (t) => { + chdirWorkspaces(); + const plugin = { + async inspect() { + return loadJson('./pip-app-transitive-vuln/inspect-result.json'); + }, + }; + const spyPlugin = sinon.spy(plugin, 'inspect'); + + const loadPlugin = sinon.stub(plugins, 'loadPlugin'); + t.teardown(loadPlugin.restore); + loadPlugin + .withArgs('pip') + .returns(plugin); + + server.setNextResponses([ + {ok: true}, + loadJson('./pip-app-transitive-vuln/response-with-remediation.json'), + ]); + t.teardown(() => server.setNextResponses([])); + try { + await cli.test('pip-app-transitive-vuln', { + file: 'requirements.txt', + }); + t.fail('should throw, since there are vulns'); + } catch (e) { + t.match(e.message, /Pin Jinja2 to 2.10.1 to fix/); + } + let req = server.popRequest(); + t.equal(req.method, 'GET', 'makes GET request'); + t.match(req.url, 'cli-config/feature-flags/pythonPinning', 'to correct url'); + req = server.popRequest(); + t.equal(req.method, 'POST', 'makes POST request'); + t.equal(req.headers['x-snyk-cli-version'], versionNumber, 'sends version number'); + t.match(req.url, '/test-dep-graph', 'posts to correct url'); + t.equal(req.body.depGraph.pkgManager.name, 'pip'); + t.same(spyPlugin.getCall(0).args, + ['pip-app-transitive-vuln', 'requirements.txt', { + args: null, + file: 'requirements.txt', + org: null, + projectName: null, + packageManager: 'pip', + path: 'pip-app-transitive-vuln', + showVulnPaths: true, + }], 'calls python plugin'); +}); + test('`test nuget-app --file=project.assets.json`', async (t) => { chdirWorkspaces(); const plugin = { diff --git a/test/acceptance/fake-server.ts b/test/acceptance/fake-server.ts index b196997887..1a5d848e91 100644 --- a/test/acceptance/fake-server.ts +++ b/test/acceptance/fake-server.ts @@ -2,10 +2,11 @@ import * as restify from 'restify'; interface FakeServer extends restify.Server { _reqLog: restify.Request[]; - _nextResponse?: restify.Response; + _nextResponseQueue: restify.Response[]; _nextStatusCode?: number; popRequest: () => restify.Request; setNextResponse: (r: any) => void; + setNextResponses: (r: any[]) => void; setNextStatusCodeAndResponse: (c: number, r: any) => void; } @@ -14,6 +15,7 @@ export function fakeServer(root, apikey) { name: 'snyk-mock-server', version: '1.0.0', }) as FakeServer; + server._nextResponseQueue = []; server._reqLog = []; server.popRequest = function () { return server._reqLog.pop()!; @@ -53,11 +55,10 @@ export function fakeServer(root, apikey) { }); server.use(function (req, res, next) { - if (!server._nextResponse && !server._nextStatusCode) { + if (!server._nextResponseQueue.length && !server._nextStatusCode) { return next(); } - var response = server._nextResponse; - delete server._nextResponse; + var response = server._nextResponseQueue.pop(); if (server._nextStatusCode) { const code = server._nextStatusCode; delete server._nextStatusCode; @@ -144,12 +145,16 @@ export function fakeServer(root, apikey) { }); server.setNextResponse = function (response) { - server._nextResponse = response; + server._nextResponseQueue = [response]; + }; + + server.setNextResponses = function (responses) { + server._nextResponseQueue = responses; }; server.setNextStatusCodeAndResponse = (code, body) => { server._nextStatusCode = code; - server._nextResponse = body; + server._nextResponseQueue = [body]; }; return server; diff --git a/test/acceptance/workspaces/pip-app-transitive-vuln/inspect-result.json b/test/acceptance/workspaces/pip-app-transitive-vuln/inspect-result.json new file mode 100644 index 0000000000..520c410548 --- /dev/null +++ b/test/acceptance/workspaces/pip-app-transitive-vuln/inspect-result.json @@ -0,0 +1,41 @@ +{ + "plugin": { + "name": "snyk-python-plugin", + "runtime": "Python 2.7.16" + }, + "package": { + "packageFormatVersion": "pip:0.0.1", + "version": "0.0.0", + "name": "pip-app-transitive-vuln", + "dependencies": { + "flask": { + "version": "0.12.2", + "name": "flask", + "dependencies": { + "itsdangerous": { + "version": "0.24", + "name": "itsdangerous" + }, + "Jinja2": { + "version": "2.9.6", + "name": "Jinja2", + "dependencies": { + "MarkupSafe": { + "version": "1.0", + "name": "MarkupSafe" + } + } + }, + "click": { + "version": "6.7", + "name": "click" + }, + "Werkzeug": { + "version": "0.12.2", + "name": "Werkzeug" + } + } + } + } + } +} \ No newline at end of file diff --git a/test/acceptance/workspaces/pip-app-transitive-vuln/requirements.txt b/test/acceptance/workspaces/pip-app-transitive-vuln/requirements.txt new file mode 100644 index 0000000000..484d3c5749 --- /dev/null +++ b/test/acceptance/workspaces/pip-app-transitive-vuln/requirements.txt @@ -0,0 +1 @@ +flask==0.12.2 diff --git a/test/acceptance/workspaces/pip-app-transitive-vuln/response-with-remediation.json b/test/acceptance/workspaces/pip-app-transitive-vuln/response-with-remediation.json new file mode 100644 index 0000000000..5131ee93c6 --- /dev/null +++ b/test/acceptance/workspaces/pip-app-transitive-vuln/response-with-remediation.json @@ -0,0 +1,490 @@ +{ + "result": { + "affectedPkgs": { + "flask@0.12.2": { + "pkg": { + "name": "flask", + "version": "0.12.2" + }, + "issues": { + "SNYK-PYTHON-FLASK-42185": { + "issueId": "SNYK-PYTHON-FLASK-42185", + "fixInfo": { + "isPatchable": false, + "upgradePaths": [ + { + "path": [ + { + "name": "pip-app-transitive-vuln", + "version": "0.0.0" + }, + { + "name": "flask", + "version": "0.12.2", + "newVersion": "0.12.3" + } + ] + } + ] + } + }, + "SNYK-PYTHON-FLASK-451637": { + "issueId": "SNYK-PYTHON-FLASK-451637", + "fixInfo": { + "isPatchable": false, + "upgradePaths": [ + { + "path": [ + { + "name": "pip-app-transitive-vuln", + "version": "0.0.0" + }, + { + "name": "flask", + "version": "0.12.2", + "newVersion": "1.0" + } + ] + } + ] + } + } + } + }, + "Jinja2@2.9.6": { + "pkg": { + "name": "Jinja2", + "version": "2.9.6" + }, + "issues": { + "SNYK-PYTHON-JINJA2-174126": { + "issueId": "SNYK-PYTHON-JINJA2-174126", + "fixInfo": { + "isPatchable": false, + "upgradePaths": [ + { + "path": [ + { + "name": "pip-app-transitive-vuln", + "version": "0.0.0" + }, + { + "name": "flask", + "version": "0.12.2", + "newVersion": "0.12.2" + }, + { + "name": "Jinja2", + "version": "2.9.6", + "isDropped": true + } + ] + } + ] + } + } + } + }, + "Werkzeug@0.12.2": { + "pkg": { + "name": "Werkzeug", + "version": "0.12.2" + }, + "issues": { + "SNYK-PYTHON-WERKZEUG-458931": { + "issueId": "SNYK-PYTHON-WERKZEUG-458931", + "fixInfo": { + "isPatchable": false, + "upgradePaths": [ + { + "path": [ + { + "name": "pip-app-transitive-vuln", + "version": "0.0.0" + }, + { + "name": "flask", + "version": "0.12.2", + "newVersion": "0.12.2" + }, + { + "name": "Werkzeug", + "version": "0.12.2", + "isDropped": true + } + ] + } + ] + } + } + } + } + }, + "issuesData": { + "SNYK-PYTHON-FLASK-42185": { + "CVSSv3": "CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H", + "alternativeIds": [], + "creationTime": "2018-08-20T19:12:29.035000Z", + "credit": [ + "Unknown" + ], + "cvssScore": 7.5, + "description": "## Overview\n[flask](https://pypi.org/project/Flask/) is a lightweight WSGI web application framework.\n\nAffected versions of this package are vulnerable to Improper Input Validation. It did not detect the encoding of incoming JSON data as one of the supported UTF encodings, and allowed arbitrary encodings from the request.\n\n## Remediation\nUpgrade `flask` to version 0.12.3 or higher.\n\n## References\n- [GitHub PR](https://github.com/pallets/flask/pull/2691)\n- [GitHub Release Tag](https://github.com/pallets/flask/releases/tag/0.12.3)\n", + "disclosureTime": "2018-04-10T19:12:29.035000Z", + "fixedIn": [ + "0.12.3" + ], + "functions": [], + "functions_new": [], + "id": "SNYK-PYTHON-FLASK-42185", + "identifiers": { + "CVE": [ + "CVE-2018-1000656" + ], + "CWE": [ + "CWE-20" + ] + }, + "language": "python", + "modificationTime": "2019-06-02T11:58:23.863763Z", + "moduleName": "flask", + "packageManager": "pip", + "packageName": "flask", + "patches": [], + "publicationTime": "2018-08-21T14:16:13.738000Z", + "references": [ + { + "title": "GitHub PR", + "url": "https://github.com/pallets/flask/pull/2691" + }, + { + "title": "GitHub Release Tag", + "url": "https://github.com/pallets/flask/releases/tag/0.12.3" + } + ], + "semver": { + "vulnerable": [ + "[,0.12.3)" + ] + }, + "severity": "high", + "title": "Improper Input Validation" + }, + "SNYK-PYTHON-FLASK-451637": { + "CVSSv3": "CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H", + "alternativeIds": [], + "creationTime": "2019-07-17T15:17:46.764958Z", + "credit": [ + "Unknown" + ], + "cvssScore": 7.5, + "description": "## Overview\n\n[Flask](https://pypi.org/project/Flask/) is a lightweight WSGI web application framework\n\n\nAffected versions of this package are vulnerable to Denial of Service (DOS).\nThe package allows for unsafe encoded JSON data to be decoded.\n\n## Remediation\n\nUpgrade `Flask` to version 1.0 or higher.\n\n\n## References\n\n- [GitHub PR](https://github.com/pallets/flask/pull/2691)\n\n- [Release Notes](https://www.palletsprojects.com/blog/flask-1-0-released/)\n", + "disclosureTime": "2019-07-17T14:56:51Z", + "fixedIn": [ + "1.0" + ], + "functions": [], + "functions_new": [], + "id": "SNYK-PYTHON-FLASK-451637", + "identifiers": { + "CVE": [ + "CVE-2019-1010083" + ], + "CWE": [ + "CWE-20" + ] + }, + "language": "python", + "modificationTime": "2019-07-17T17:05:27.527509Z", + "moduleName": "flask", + "packageManager": "pip", + "packageName": "flask", + "patches": [], + "publicationTime": "2019-07-17T14:56:51Z", + "references": [ + { + "title": "GitHub PR", + "url": "https://github.com/pallets/flask/pull/2691" + }, + { + "title": "Release Notes", + "url": "https://www.palletsprojects.com/blog/flask-1-0-released/" + } + ], + "semver": { + "vulnerable": [ + "[,1.0)" + ] + }, + "severity": "high", + "title": "Denial of Service (DOS)" + }, + "SNYK-PYTHON-JINJA2-174126": { + "CVSSv3": "CVSS:3.0/AV:N/AC:H/PR:L/UI:N/S:C/C:L/I:L/A:L/RL:O", + "alternativeIds": [], + "creationTime": "2019-04-07T10:24:16.310959Z", + "credit": [ + "Unknown" + ], + "cvssScore": 6, + "description": "## Overview\n\n[jinja2](https://pypi.org/project/Jinja2/) is a template engine written in pure Python. It provides a Django inspired non-XML syntax but supports inline expressions and an optional sandboxed environment.\n\n\nAffected versions of this package are vulnerable to Sandbox Escape\nvia the `str.format_map`.\n\n## Remediation\n\nUpgrade `jinja2` to version 2.10.1 or higher.\n\n\n## References\n\n- [Release Notes](https://palletsprojects.com/blog/jinja-2-10-1-released)\n", + "disclosureTime": "2019-04-07T00:42:43Z", + "fixedIn": [ + "2.10.1" + ], + "functions": [], + "functions_new": [], + "id": "SNYK-PYTHON-JINJA2-174126", + "identifiers": { + "CVE": [ + "CVE-2019-10906" + ], + "CWE": [ + "CWE-265" + ] + }, + "language": "python", + "modificationTime": "2019-04-07T13:13:03.054711Z", + "moduleName": "jinja2", + "packageManager": "pip", + "packageName": "Jinja2", + "patches": [], + "publicationTime": "2019-04-07T00:42:43Z", + "references": [ + { + "title": "Release Notes", + "url": "https://palletsprojects.com/blog/jinja-2-10-1-released" + } + ], + "semver": { + "vulnerable": [ + "[,2.10.1)" + ] + }, + "severity": "medium", + "title": "Sandbox Escape" + }, + "SNYK-PYTHON-WERKZEUG-458931": { + "CVSSv3": "CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:N", + "alternativeIds": [], + "creationTime": "2019-08-10T08:00:09.852965Z", + "credit": [ + "Unknown" + ], + "cvssScore": 9.1, + "description": "## Overview\n\n[Werkzeug](https://werkzeug.palletsprojects.com/) is a WSGI web application library.\n\n\nAffected versions of this package are vulnerable to Insufficient Randomness\nwhen used with Docker, it has insufficient debugger PIN randomness because Docker containers share the same machine id.\n\n## Remediation\n\nUpgrade `Werkzeug` to version 0.15.3 or higher.\n\n\n## References\n\n- [GitHub Fix Commit](https://github.com/pallets/werkzeug/commit/00bc43b1672e662e5e3b8cecd79e67fc968fa246)\n\n- [Release Notes](https://palletsprojects.com/blog/werkzeug-0-15-3-released/)\n", + "disclosureTime": "2019-08-09T16:11:50Z", + "fixedIn": [ + "0.15.3" + ], + "functions": [], + "functions_new": [], + "id": "SNYK-PYTHON-WERKZEUG-458931", + "identifiers": { + "CVE": [ + "CVE-2019-14806" + ], + "CWE": [ + "CWE-310" + ] + }, + "language": "python", + "modificationTime": "2019-08-11T08:49:08.544640Z", + "moduleName": "werkzeug", + "packageManager": "pip", + "packageName": "Werkzeug", + "patches": [], + "publicationTime": "2019-08-11T07:58:24Z", + "references": [ + { + "title": "GitHub Fix Commit", + "url": "https://github.com/pallets/werkzeug/commit/00bc43b1672e662e5e3b8cecd79e67fc968fa246" + }, + { + "title": "Release Notes", + "url": "https://palletsprojects.com/blog/werkzeug-0-15-3-released/" + } + ], + "semver": { + "vulnerable": [ + "[,0.15.3)" + ] + }, + "severity": "high", + "title": "Insufficient Randomness" + } + }, + "remediation": { + "unresolved": [ + { + "CVSSv3": "CVSS:3.0/AV:N/AC:H/PR:L/UI:N/S:C/C:L/I:L/A:L/RL:O", + "alternativeIds": [], + "creationTime": "2019-04-07T10:24:16.310959Z", + "credit": [ + "Unknown" + ], + "cvssScore": 6, + "description": "## Overview\n\n[jinja2](https://pypi.org/project/Jinja2/) is a template engine written in pure Python. It provides a Django inspired non-XML syntax but supports inline expressions and an optional sandboxed environment.\n\n\nAffected versions of this package are vulnerable to Sandbox Escape\nvia the `str.format_map`.\n\n## Remediation\n\nUpgrade `jinja2` to version 2.10.1 or higher.\n\n\n## References\n\n- [Release Notes](https://palletsprojects.com/blog/jinja-2-10-1-released)\n", + "disclosureTime": "2019-04-07T00:42:43Z", + "fixedIn": [ + "2.10.1" + ], + "functions": [], + "functions_new": [], + "id": "SNYK-PYTHON-JINJA2-174126", + "identifiers": { + "CVE": [ + "CVE-2019-10906" + ], + "CWE": [ + "CWE-265" + ] + }, + "language": "python", + "modificationTime": "2019-04-07T13:13:03.054711Z", + "moduleName": "jinja2", + "packageManager": "pip", + "packageName": "Jinja2", + "patches": [], + "publicationTime": "2019-04-07T00:42:43Z", + "references": [ + { + "title": "Release Notes", + "url": "https://palletsprojects.com/blog/jinja-2-10-1-released" + } + ], + "semver": { + "vulnerable": [ + "[,2.10.1)" + ] + }, + "severity": "medium", + "title": "Sandbox Escape", + "from": [ + "pip-app-transitive-vuln@0.0.0", + "flask@0.12.2", + "Jinja2@2.9.6" + ], + "upgradePath": [ + false, + "flask@0.12.2" + ], + "isUpgradable": true, + "isPatchable": false, + "name": "Jinja2", + "version": "2.9.6" + }, + { + "CVSSv3": "CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:N", + "alternativeIds": [], + "creationTime": "2019-08-10T08:00:09.852965Z", + "credit": [ + "Unknown" + ], + "cvssScore": 9.1, + "description": "## Overview\n\n[Werkzeug](https://werkzeug.palletsprojects.com/) is a WSGI web application library.\n\n\nAffected versions of this package are vulnerable to Insufficient Randomness\nwhen used with Docker, it has insufficient debugger PIN randomness because Docker containers share the same machine id.\n\n## Remediation\n\nUpgrade `Werkzeug` to version 0.15.3 or higher.\n\n\n## References\n\n- [GitHub Fix Commit](https://github.com/pallets/werkzeug/commit/00bc43b1672e662e5e3b8cecd79e67fc968fa246)\n\n- [Release Notes](https://palletsprojects.com/blog/werkzeug-0-15-3-released/)\n", + "disclosureTime": "2019-08-09T16:11:50Z", + "fixedIn": [ + "0.15.3" + ], + "functions": [], + "functions_new": [], + "id": "SNYK-PYTHON-WERKZEUG-458931", + "identifiers": { + "CVE": [ + "CVE-2019-14806" + ], + "CWE": [ + "CWE-310" + ] + }, + "language": "python", + "modificationTime": "2019-08-11T08:49:08.544640Z", + "moduleName": "werkzeug", + "packageManager": "pip", + "packageName": "Werkzeug", + "patches": [], + "publicationTime": "2019-08-11T07:58:24Z", + "references": [ + { + "title": "GitHub Fix Commit", + "url": "https://github.com/pallets/werkzeug/commit/00bc43b1672e662e5e3b8cecd79e67fc968fa246" + }, + { + "title": "Release Notes", + "url": "https://palletsprojects.com/blog/werkzeug-0-15-3-released/" + } + ], + "semver": { + "vulnerable": [ + "[,0.15.3)" + ] + }, + "severity": "high", + "title": "Insufficient Randomness", + "from": [ + "pip-app-transitive-vuln@0.0.0", + "flask@0.12.2", + "Werkzeug@0.12.2" + ], + "upgradePath": [ + false, + "flask@0.12.2" + ], + "isUpgradable": true, + "isPatchable": false, + "name": "Werkzeug", + "version": "0.12.2" + } + ], + "upgrade": { + "flask@0.12.2": { + "upgradeTo": "flask@1.0", + "upgrades": [ + "flask@0.12.2", + "flask@0.12.2" + ], + "vulns": [ + "SNYK-PYTHON-FLASK-451637", + "SNYK-PYTHON-FLASK-42185" + ] + } + }, + "patch": {}, + "ignore": {}, + "pin": { + "flask": { + "upgradeTo": "1.0", + "vulns": [ + "SNYK-PYTHON-FLASK-42185", + "SNYK-PYTHON-FLASK-451637" + ], + "isTransitive": false + }, + "Jinja2": { + "upgradeTo": "2.10.1", + "vulns": [ + "SNYK-PYTHON-JINJA2-174126" + ], + "isTransitive": true + }, + "Werkzeug": { + "upgradeTo": "0.15.3", + "vulns": [ + "SNYK-PYTHON-WERKZEUG-458931" + ], + "isTransitive": true + } + } + } + }, + "meta": { + "isPublic": false, + "isLicensesEnabled": false, + "licensesPolicy": null, + "policy": "# Snyk (https://snyk.io) policy file, patches or ignores known vulnerabilities.\nversion: v1.13.5\nignore: {}\npatch: {}\n", + "ignoreSettings": null, + "org": "kyegupov" + }, + "filesystemPolicy": false +} \ No newline at end of file