Skip to content

Commit

Permalink
Merge pull request #147 from snyk/feat/add-reachable-vulnerabilities
Browse files Browse the repository at this point in the history
feat: support reachable vulns for gradle
  • Loading branch information
Mila Votradovec authored Sep 23, 2020
2 parents 88ea684 + e104cc0 commit 453a81e
Show file tree
Hide file tree
Showing 5 changed files with 130 additions and 0 deletions.
16 changes: 16 additions & 0 deletions lib/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,12 @@ import { MissingSubProjectError } from './errors';
import * as chalk from 'chalk';
import { DepGraphBuilder, PkgManager, DepGraph } from '@snyk/dep-graph';
import { legacyCommon, legacyPlugin as api } from '@snyk/cli-interface';
import * as javaCallGraphBuilder from '@snyk/java-call-graph-builder';
import debugModule = require('debug');
import { findCycles } from './find-cycles';

type ScannedProject = legacyCommon.ScannedProject;
type CallGraph = legacyCommon.CallGraph;

// To enable debugging output, use `snyk -d`
let logger: debugModule.Debugger | null = null;
Expand Down Expand Up @@ -59,6 +61,7 @@ export interface GradleInspectOptions {
// Gradle process just never exits, from the Node's standpoint.
// Leaving default usage `--no-daemon`, because of backwards compatibility
daemon?: boolean;
reachableVulns?: boolean;
}

type Options = api.InspectOptions & GradleInspectOptions;
Expand Down Expand Up @@ -105,6 +108,17 @@ export async function inspect(
targetFile: targetFileFilteredForCompatibility(targetFile),
meta: {},
};

let callGraph: CallGraph | undefined;
const targetPath = path.join(root, targetFile);
if (options.reachableVulns) {
debugLog(`getting call graph from path ${targetPath}`);
callGraph = await javaCallGraphBuilder.getCallGraphGradle(
path.dirname(targetPath),
);
debugLog('got call graph successfully');
}

if (api.isMultiSubProject(options)) {
if (subProject) {
throw new Error(
Expand All @@ -120,6 +134,7 @@ export async function inspect(
return {
plugin,
scannedProjects,
callGraph,
};
}
const depGraphAndDepRootNames = await getAllDepsOneProject(
Expand All @@ -136,6 +151,7 @@ export async function inspect(
return {
plugin,
package: null, //TODO @boost: delete me once cli-interface makes it optional
callGraph,
dependencyGraph: depGraphAndDepRootNames.depGraph,
meta: {
gradleProjectName: depGraphAndDepRootNames.gradleProjectName,
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@
"dependencies": {
"@snyk/cli-interface": "2.9.1",
"@snyk/dep-graph": "^1.19.4",
"@snyk/java-call-graph-builder": "^1.14.0",
"@types/debug": "^4.1.4",
"chalk": "^3.0.0",
"debug": "^4.1.1",
Expand Down
33 changes: 33 additions & 0 deletions test/fixtures/call-graphs/simple.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
{
"options": {
"directed": true,
"multigraph": false,
"compound": false
},
"nodes": [
{
"v": "com.ibm.wala.FakeRootClass:fakeRootMethod",
"value": {
"className": "com.ibm.wala.FakeRootClass",
"functionName": "fakeRootMethod"
}
},
{
"v": "ch.qos.logback.classic.net.SocketNode:run",
"value": {
"className": "ch.qos.logback.classic.net.SocketNode",
"functionName": "run"
}
}
],
"edges": [
{
"v": "com.ibm.wala.FakeRootClass:fakeRootMethod",
"w": "com.ibm.wala.FakeRootClass:fakeWorldClinit"
},
{
"v": "ch.qos.logback.classic.net.SocketNode",
"w": "com.ibm.wala.FakeRootClass:fakeWorldClinit"
}
]
}
42 changes: 42 additions & 0 deletions test/fixtures/java-reachability-playground/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/*
* This file was generated by the Gradle 'init' task.
*/

plugins {
id 'java'
id 'maven-publish'
id 'application'
}

apply plugin : "java"
ext {
javaMainClass = "Unzipper"
}

application {
mainClassName = javaMainClass
}

repositories {
mavenLocal()
maven {
url = uri('https://repo.maven.apache.org/maven2')
}
}

dependencies {
implementation 'commons-collections:commons-collections:3.2.1'
implementation 'org.nd4j:nd4j-common:1.0.0-beta2'
}

group = 'org.example'
version = '1.0-SNAPSHOT'
sourceCompatibility = '1.8'

publishing {
publications {
maven(MavenPublication) {
from(components.java)
}
}
}
38 changes: 38 additions & 0 deletions test/system/plugin.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@ import { fixtureDir } from '../common';
import { test } from 'tap';
import { inspect } from '../../lib';
import * as subProcess from '../../lib/sub-process';
import * as fs from 'fs';
import * as sinon from 'sinon';
import * as javaCallGraphBuilder from '@snyk/java-call-graph-builder';
import { CallGraph } from '@snyk/cli-interface/legacy/common';

const rootNoWrapper = fixtureDir('no wrapper');
const GRADLE_VERSION = process.env.GRADLE_VERSION;
Expand All @@ -21,6 +25,40 @@ test('run inspect()', async (t) => {
);
});

test('run inspect() with reachableVulns', async (t) => {
const gradleCallGraph = JSON.parse(
fs.readFileSync(
path.join(fixtureDir('call-graphs'), 'simple.json'),
'utf-8',
),
);
const javaCallGraphBuilderStub = sinon
.stub(javaCallGraphBuilder, 'getCallGraphGradle')
.resolves(gradleCallGraph as CallGraph);
const result = await inspect('.', path.join(rootNoWrapper, 'build.gradle'), {
reachableVulns: true,
});
const pkgs = result.dependencyGraph.getDepPkgs();
const nodeIds: string[] = [];
Object.keys(pkgs).forEach((id) => {
nodeIds.push(`${pkgs[id].name}@${pkgs[id].version}`);
});

t.ok(
nodeIds.indexOf('com.android.tools:annotations@25.3.0') !== -1,
'correct version found',
);
t.ok(javaCallGraphBuilderStub.calledOnce, 'called to the call graph builder');
t.ok(
javaCallGraphBuilderStub.calledWith(path.join('.', rootNoWrapper)),
'call graph builder was called with the correct path',
);
t.same(gradleCallGraph, result.callGraph, 'returns expected callgraph');
t.teardown(() => {
javaCallGraphBuilderStub.restore();
});
});

test('multi-config: both compile and runtime deps picked up by default', async (t) => {
const result = await inspect(
'.',
Expand Down

0 comments on commit 453a81e

Please sign in to comment.