-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: support maven reachable vulnerabilities for
snyk test
Will send a call graph to registry if the --reachable-vulns flag is being passed. The function call graph is generated by the maven plugin. This is only supported behind the reachableVulns feature flag for the maven package manager.
- Loading branch information
Dar Malovani
committed
Apr 21, 2020
1 parent
f7097e3
commit 8b805e1
Showing
17 changed files
with
445 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
11 changes: 11 additions & 0 deletions
11
src/lib/errors/feature-not-supported-by-package-manager-error.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
import { CustomError } from './custom-error'; | ||
import { SupportedPackageManagers } from '../package-managers'; | ||
|
||
export class FeatureNotSupportedByPackageManagerError extends CustomError { | ||
constructor(feature: string, packageManager: SupportedPackageManagers) { | ||
super(`Unsupported package manager ${packageManager} for ${feature}.`); | ||
this.code = 422; | ||
|
||
this.userMessage = `'${feature}' is not supported for package manager '${packageManager}'.`; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
import * as graphlib from 'graphlib'; | ||
import { CallGraph } from '@snyk/cli-interface/legacy/common'; | ||
|
||
import { | ||
REACHABLE_VULNS_SUPPORTED_PACKAGE_MANAGERS, | ||
SupportedPackageManagers, | ||
} from './package-managers'; | ||
import { isFeatureFlagSupportedForOrg } from './feature-flags'; | ||
import { | ||
AuthFailedError, | ||
FeatureNotSupportedByPackageManagerError, | ||
UnsupportedFeatureFlagError, | ||
} from './errors'; | ||
|
||
const featureFlag = 'reachableVulns'; | ||
|
||
export function serializeCallGraphWithMetrics( | ||
callGraph: CallGraph, | ||
): { | ||
callGraph: any; | ||
nodeCount: number; | ||
edgeCount: number; | ||
} { | ||
return { | ||
callGraph: graphlib.json.write(callGraph), | ||
nodeCount: callGraph.nodeCount(), | ||
edgeCount: callGraph.edgeCount(), | ||
}; | ||
} | ||
|
||
export async function validatePayload( | ||
packageManager: SupportedPackageManagers, | ||
org: any, | ||
): Promise<boolean> { | ||
if (!REACHABLE_VULNS_SUPPORTED_PACKAGE_MANAGERS.includes(packageManager)) { | ||
throw new FeatureNotSupportedByPackageManagerError( | ||
'Reachable vulns', | ||
packageManager, | ||
); | ||
} | ||
const reachableVulnsSupportedRes = await isFeatureFlagSupportedForOrg( | ||
featureFlag, | ||
org, | ||
); | ||
|
||
if (reachableVulnsSupportedRes.code === 401) { | ||
throw AuthFailedError( | ||
reachableVulnsSupportedRes.error, | ||
reachableVulnsSupportedRes.code, | ||
); | ||
} | ||
if (reachableVulnsSupportedRes.userMessage) { | ||
throw new UnsupportedFeatureFlagError( | ||
featureFlag, | ||
reachableVulnsSupportedRes.userMessage, | ||
); | ||
} | ||
return true; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
import { Options, TestOptions } from '../types'; | ||
import * as config from '../config'; | ||
import { SupportedPackageManagers } from '../package-managers'; | ||
import * as reachableVulns from '../reachable-vulns'; | ||
|
||
export async function validateOptions(options: Options & TestOptions) { | ||
if (options.reachableVulns) { | ||
const pkgManager = options.packageManager as SupportedPackageManagers; | ||
const org = options.org || config.org; | ||
await reachableVulns.validatePayload(pkgManager, org); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
import * as tap from 'tap'; | ||
import * as cli from '../../src/cli/commands'; | ||
import { fakeServer } from './fake-server'; | ||
|
||
const { test, only } = tap; | ||
(tap as any).runOnly = false; // <- for debug. set to true, and replace a test to only(..) | ||
|
||
const port = (process.env.PORT = process.env.SNYK_PORT = '12345'); | ||
process.env.SNYK_API = 'http://localhost:' + port + '/api/v1'; | ||
process.env.SNYK_HOST = 'http://localhost:' + port; | ||
process.env.LOG_LEVEL = '0'; | ||
const apiKey = '123456789'; | ||
let oldkey; | ||
let oldendpoint; | ||
const server = fakeServer(process.env.SNYK_API, apiKey); | ||
const before = tap.runOnly ? only : test; | ||
const after = tap.runOnly ? only : test; | ||
|
||
// @later: remove this config stuff. | ||
// Was copied straight from ../src/cli-server.js | ||
before('setup', async (t) => { | ||
t.plan(3); | ||
let key = await cli.config('get', 'api'); | ||
oldkey = key; | ||
t.pass('existing user config captured'); | ||
|
||
key = await cli.config('get', 'endpoint'); | ||
oldendpoint = key; | ||
t.pass('existing user endpoint captured'); | ||
|
||
await new Promise((resolve) => { | ||
server.listen(port, resolve); | ||
}); | ||
t.pass('started demo server'); | ||
t.end(); | ||
}); | ||
|
||
// @later: remove this config stuff. | ||
// Was copied straight from ../src/cli-server.js | ||
before('prime config', async (t) => { | ||
await cli.config('set', 'api=' + apiKey); | ||
t.pass('api token set'); | ||
await cli.config('unset', 'endpoint'); | ||
t.pass('endpoint removed'); | ||
t.end(); | ||
}); | ||
|
||
test('test vulnerable project with --reachable-vulns not supported package manager', async (t) => { | ||
try { | ||
await cli.test('gradle', { | ||
reachableVulns: true, | ||
}); | ||
t.fail('expected test to throw exception'); | ||
} catch (err) { | ||
t.equal(err.code, 422, 'should throw exception'); | ||
t.equal( | ||
err.userMessage, | ||
`'Reachable vulns' is not supported for package manager 'npm'.`, | ||
'correct user message', | ||
); | ||
} | ||
}); | ||
|
||
// @later: try and remove this config stuff | ||
// Was copied straight from ../src/cli-server.js | ||
after('teardown', async (t) => { | ||
t.plan(4); | ||
|
||
delete process.env.SNYK_API; | ||
delete process.env.SNYK_HOST; | ||
delete process.env.SNYK_PORT; | ||
t.notOk(process.env.SNYK_PORT, 'fake env values cleared'); | ||
|
||
await new Promise((resolve) => { | ||
server.close(resolve); | ||
}); | ||
t.pass('server shutdown'); | ||
let key = 'set'; | ||
let value = 'api=' + oldkey; | ||
if (!oldkey) { | ||
key = 'unset'; | ||
value = 'api'; | ||
} | ||
await cli.config(key, value); | ||
t.pass('user config restored'); | ||
if (oldendpoint) { | ||
await cli.config('endpoint', oldendpoint); | ||
t.pass('user endpoint restored'); | ||
t.end(); | ||
} else { | ||
t.pass('no endpoint'); | ||
t.end(); | ||
} | ||
}); |
Oops, something went wrong.