Skip to content

Commit

Permalink
src/goVulncheck: report unaffecting vulnerabilities separately
Browse files Browse the repository at this point in the history
Unaffecting vulnerabilities = affect the required modules but call
paths to the vulnerable symbols from the analyzed packages are not
found.

And, in the run summary section, report the count of affecting
vulnerabilities.

Change-Id: I9ddd0ffed4286e9e942a056ee299d438f8b5f21a
Reviewed-on: https://go-review.googlesource.com/c/vscode-go/+/412317
Run-TryBot: Hyang-Ah Hana Kim <[email protected]>
Reviewed-by: Jamal Carvalho <[email protected]>
TryBot-Result: kokoro <[email protected]>
  • Loading branch information
hyangah committed Jun 24, 2022
1 parent 445a42f commit 78149ef
Show file tree
Hide file tree
Showing 4 changed files with 57 additions and 15 deletions.
35 changes: 29 additions & 6 deletions media/vulncheckView.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@

const logContainer = /** @type {HTMLElement} */ (document.querySelector('.log'));
const vulnsContainer = /** @type {HTMLElement} */ (document.querySelector('.vulns'));
const unaffectingContainer = /** @type {HTMLElement} */ (document.querySelector('.unaffecting'));

vulnsContainer.addEventListener('click', (event) => {
let node = event && event.target;
Expand All @@ -37,7 +38,12 @@
}

function snapshotContent() {
return vulnsContainer.innerHTML;
const res = {
'log': logContainer.innerHTML,
'vulns': vulnsContainer.innerHTML,
'unaffecting': unaffectingContainer.innerHTML
};
return JSON.stringify(res);
}

/**
Expand All @@ -61,16 +67,19 @@
return durationMillisec ? `${startDate} (took ${durationMillisec} msec)` : `${startDate}`;
}

const vulns = json.Vuln || [];
const affecting = vulns.filter((v) => v.CallStackSummaries?.length);
const unaffecting = vulns.filter((v) => !v.CallStackSummaries?.length);

runLog.innerHTML = `
<tr><td>Dir:</td><td>${json.Dir || ''}</td></tr>
<tr><td>Pattern:</td><td>${json.Pattern || ''}</td></tr>
<tr><td>Analyzed at:</td><td>${timeinfo(json.Start, json.Duration)}</td></tr>`;
<tr><td>Analyzed at:</td><td>${timeinfo(json.Start, json.Duration)}</td></tr>
<tr><td>Found ${affecting?.length || 0} known vulnerabilities</td></tr>`;
logContainer.appendChild(runLog);

const vulns = json.Vuln || [];
vulnsContainer.innerHTML = '';

vulns.forEach((vuln) => {
affecting.forEach((vuln) => {
const element = document.createElement('div');
element.className = 'vuln';
vulnsContainer.appendChild(element);
Expand All @@ -92,7 +101,7 @@
details.className = 'vuln-details'
details.innerHTML = `
<tr><td>Package</td><td>${vuln.PkgPath}</td></tr>
<tr><td>Current Version</td><td>${moduleVersion(vuln.ModPath, vuln.CurrentVersion)}</td></tr>
<tr><td>Found in Version</td><td>${moduleVersion(vuln.ModPath, vuln.CurrentVersion)}</td></tr>
<tr><td>Fixed Version</td><td>${moduleVersion(vuln.ModPath, vuln.FixedVersion)}</td></tr>
<tr><td>Affecting</td><td>${vuln.AffectedPkgs?.join('<br>')}</td></tr>
`;
Expand Down Expand Up @@ -131,6 +140,20 @@
examples.appendChild(callstacksContainer);
element.appendChild(examples);
});

unaffectingContainer.innerText = '';
if (unaffecting.length > 0) {
unaffectingContainer.innerHTML = '<hr></hr><p>These vulnerabilities exist in required modules, but no vulnerable symbols are used.<br>No action is required. For more information, visit <a href="https://pkg.go.dev/vuln">https://pkg.go.dev/vuln</a></p>';

const details = document.createElement('table');
unaffecting.forEach((vuln) => {
const row = document.createElement('tr');
row.className = 'vuln-details'
row.innerHTML = `<tr><td>${vuln.ModPath}</td><td><a href="${vuln.URL}">${vuln.ID}</a></td></tr>`;
details.appendChild(row);
});
unaffectingContainer.appendChild(details);
}
}

// Message Passing between Extension and Webview
Expand Down
8 changes: 4 additions & 4 deletions src/goVulncheck.ts
Original file line number Diff line number Diff line change
Expand Up @@ -97,9 +97,9 @@ export class VulncheckResultViewProvider implements vscode.CustomTextEditorProvi
<title>Vulnerability Report - govulncheck</title>
</head>
<body>
<div class="log"></div>
<div class="log"></div>
<div class="vulns"></div>
<div class="unaffecting"></div>
<script nonce="${nonce}" src="${scriptUri}"></script>
</body>
</html>`;
Expand Down Expand Up @@ -201,7 +201,7 @@ export class VulncheckProvider {
const start = new Date();
const vuln = await vulncheck(goCtx, dir, pattern, this.channel);

if (vuln) {
if (vuln?.Vuln?.length) {
fillAffectedPkgs(vuln.Vuln);

// record run info.
Expand All @@ -222,7 +222,7 @@ export class VulncheckProvider {
VulncheckResultViewProvider.viewType,
viewColumn
);
this.channel.appendLine(`Vulncheck - result wrote in ${fname}`);
this.channel.appendLine(`Vulncheck - result written in ${fname}`);
} else {
this.channel.appendLine('Vulncheck - found no vulnerability');
}
Expand Down
22 changes: 17 additions & 5 deletions test/gopls/vulncheck.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,11 +49,22 @@ suite('vulncheck result viewer tests', () => {
const res = await watcher;

assert.deepStrictEqual(res.type, 'snapshot-result', `want snapshot-result, got ${JSON.stringify(res)}`);
assert(res.target && res.target.includes('GO-2021-0113'), res.target);
// res.target type is defined in vulncheckView.js.
const { log = '', vulns = '', unaffecting = '' } = JSON.parse(res.target ?? '{}');

assert(
log.includes('Found 1 known vulnerabilities'),
`expected "1 known vulnerabilities", got ${JSON.stringify(res.target)}`
);
assert(
vulns.includes('GO-2021-0113') &&
vulns.includes('<td>Affecting</td><td>github.com/golang/vscode-go/test/testdata/vuln</td>'),
`expected "Affecting" section, got ${JSON.stringify(res.target)}`
);
// Unaffecting vulnerability's detail is omitted, but its ID is reported.
assert(
res.target &&
res.target.includes('<td>Affecting</td><td>github.com/golang/vscode-go/test/testdata/vuln</td>'),
res.target
unaffecting.includes('GO-2021-0000') && unaffecting.includes('golang.org/x/text'),
`expected reports about unaffecting vulns, got ${JSON.stringify(res.target)}`
);
});

Expand All @@ -77,7 +88,8 @@ suite('vulncheck result viewer tests', () => {
webviewPanel.webview.postMessage({ type: 'snapshot-request' });
const res = await watcher;
assert.deepStrictEqual(res.type, 'snapshot-result', `want snapshot-result, got ${JSON.stringify(res)}`);
assert(!res.target, res.target);
const { log = '', vulns = '', unaffecting = '' } = JSON.parse(res.target ?? '{}');
assert(!log && !vulns && !unaffecting, res.target);
});

// TODO: test corrupted/incomplete json file handling.
Expand Down
7 changes: 7 additions & 0 deletions test/testdata/vuln/test.vulncheck.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,13 @@
"CallStackSummaries": [
"github.com/golang/vscode-go/test/testdata/vuln.main calls golang.org/x/text/language.Parse"
]
},
{
"ID": "GO-2021-0000",
"Details": "Bogus Report",
"Symbol": "Parse",
"ModPath": "golang.org/x/text",
"URL": "https://pkg.go.dev/vuln/GO-2021-0000"
}
],
"Start": "2022-05-16T13:43:54.437Z",
Expand Down

0 comments on commit 78149ef

Please sign in to comment.