From eafb5f91d257727f79f4cc0433b83d394eb93849 Mon Sep 17 00:00:00 2001 From: Connor Clark Date: Fri, 28 Jun 2019 15:16:48 -0700 Subject: [PATCH 1/8] deps(snyk): do not allow * in semver --- .../audits/dobetterweb/no-vulnerable-libraries-test.js | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/lighthouse-core/test/audits/dobetterweb/no-vulnerable-libraries-test.js b/lighthouse-core/test/audits/dobetterweb/no-vulnerable-libraries-test.js index ef65ff78c428..71aa6e1b06d7 100644 --- a/lighthouse-core/test/audits/dobetterweb/no-vulnerable-libraries-test.js +++ b/lighthouse-core/test/audits/dobetterweb/no-vulnerable-libraries-test.js @@ -99,3 +99,13 @@ describe('Avoids front-end JavaScript libraries with known vulnerabilities', () assert.equal(auditResult.score, 1); }); }); + +describe('No glob in snyk', () => { + for (const vulns of Object.values(NoVulnerableLibrariesAudit.snykDB.npm)) { + for (const vuln of vulns) { + for (const semver of vuln.semver.vulnerable) { + assert.notEqual(semver, '*'); + } + } + } +}); From a24a38e3fb5573901ba78432c9cb7bbf52d2f0b1 Mon Sep 17 00:00:00 2001 From: Connor Clark Date: Fri, 28 Jun 2019 15:39:50 -0700 Subject: [PATCH 2/8] assert upper bounds --- .../audits/dobetterweb/no-vulnerable-libraries-test.js | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/lighthouse-core/test/audits/dobetterweb/no-vulnerable-libraries-test.js b/lighthouse-core/test/audits/dobetterweb/no-vulnerable-libraries-test.js index 71aa6e1b06d7..6d060b1f70c9 100644 --- a/lighthouse-core/test/audits/dobetterweb/no-vulnerable-libraries-test.js +++ b/lighthouse-core/test/audits/dobetterweb/no-vulnerable-libraries-test.js @@ -104,7 +104,14 @@ describe('No glob in snyk', () => { for (const vulns of Object.values(NoVulnerableLibrariesAudit.snykDB.npm)) { for (const vuln of vulns) { for (const semver of vuln.semver.vulnerable) { - assert.notEqual(semver, '*'); + assert.notEqual(semver, '*', 'invalid semver: * is not allowed'); + + const clauses = semver.split('||'); + for (const clause of clauses) { + if (!clause.trim().startsWith('=') && !clause.includes('<')) { + assert.fail(`invalid semver: ${semver}. Must contain an upper bound`); + } + } } } } From a006050e627c803fe73e863732ebb8b688f65aaa Mon Sep 17 00:00:00 2001 From: Connor Clark Date: Fri, 28 Jun 2019 15:40:47 -0700 Subject: [PATCH 3/8] update test name --- .../test/audits/dobetterweb/no-vulnerable-libraries-test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lighthouse-core/test/audits/dobetterweb/no-vulnerable-libraries-test.js b/lighthouse-core/test/audits/dobetterweb/no-vulnerable-libraries-test.js index 6d060b1f70c9..24daeb1d8568 100644 --- a/lighthouse-core/test/audits/dobetterweb/no-vulnerable-libraries-test.js +++ b/lighthouse-core/test/audits/dobetterweb/no-vulnerable-libraries-test.js @@ -100,7 +100,7 @@ describe('Avoids front-end JavaScript libraries with known vulnerabilities', () }); }); -describe('No glob in snyk', () => { +describe('Every snyk vulnerability has an upperbound', () => { for (const vulns of Object.values(NoVulnerableLibrariesAudit.snykDB.npm)) { for (const vuln of vulns) { for (const semver of vuln.semver.vulnerable) { From ba9bc7c6ec2ed7153ae68a46fb39a201062af04e Mon Sep 17 00:00:00 2001 From: Connor Clark Date: Mon, 8 Jul 2019 15:40:22 -0700 Subject: [PATCH 4/8] add comment --- .../test/audits/dobetterweb/no-vulnerable-libraries-test.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/lighthouse-core/test/audits/dobetterweb/no-vulnerable-libraries-test.js b/lighthouse-core/test/audits/dobetterweb/no-vulnerable-libraries-test.js index 24daeb1d8568..bb33ebe96902 100644 --- a/lighthouse-core/test/audits/dobetterweb/no-vulnerable-libraries-test.js +++ b/lighthouse-core/test/audits/dobetterweb/no-vulnerable-libraries-test.js @@ -104,6 +104,11 @@ describe('Every snyk vulnerability has an upperbound', () => { for (const vulns of Object.values(NoVulnerableLibrariesAudit.snykDB.npm)) { for (const vuln of vulns) { for (const semver of vuln.semver.vulnerable) { + // Examples of what semver can be: + // <1.12.2 + // >=1.12.3 <2.2.2 + // >=2.2.3 <3.0.0 + // >=3.0.0 <3.10.1 || =3.10.2 assert.notEqual(semver, '*', 'invalid semver: * is not allowed'); const clauses = semver.split('||'); From e01212b0e4396f02f1f5d78ac77cedd527f66fa4 Mon Sep 17 00:00:00 2001 From: Connor Clark Date: Mon, 8 Jul 2019 17:05:38 -0700 Subject: [PATCH 5/8] Update lighthouse-core/test/audits/dobetterweb/no-vulnerable-libraries-test.js Co-Authored-By: Brendan Kenny --- .../test/audits/dobetterweb/no-vulnerable-libraries-test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lighthouse-core/test/audits/dobetterweb/no-vulnerable-libraries-test.js b/lighthouse-core/test/audits/dobetterweb/no-vulnerable-libraries-test.js index bb33ebe96902..26efa7a9c589 100644 --- a/lighthouse-core/test/audits/dobetterweb/no-vulnerable-libraries-test.js +++ b/lighthouse-core/test/audits/dobetterweb/no-vulnerable-libraries-test.js @@ -100,7 +100,7 @@ describe('Avoids front-end JavaScript libraries with known vulnerabilities', () }); }); -describe('Every snyk vulnerability has an upperbound', () => { +describe('every snyk vulnerability has an upper bound', () => { for (const vulns of Object.values(NoVulnerableLibrariesAudit.snykDB.npm)) { for (const vuln of vulns) { for (const semver of vuln.semver.vulnerable) { From 6ec1ae139d7907718e88c4feeefd44c2ac354ae0 Mon Sep 17 00:00:00 2001 From: Connor Clark Date: Mon, 8 Jul 2019 17:57:03 -0700 Subject: [PATCH 6/8] semver.Range --- .../no-vulnerable-libraries-test.js | 39 +++++++++++++------ 1 file changed, 27 insertions(+), 12 deletions(-) diff --git a/lighthouse-core/test/audits/dobetterweb/no-vulnerable-libraries-test.js b/lighthouse-core/test/audits/dobetterweb/no-vulnerable-libraries-test.js index bb33ebe96902..c64f839f187b 100644 --- a/lighthouse-core/test/audits/dobetterweb/no-vulnerable-libraries-test.js +++ b/lighthouse-core/test/audits/dobetterweb/no-vulnerable-libraries-test.js @@ -8,6 +8,7 @@ const NoVulnerableLibrariesAudit = require('../../../audits/dobetterweb/no-vulnerable-libraries.js'); const assert = require('assert'); +const semver = require('semver'); /* eslint-env jest */ describe('Avoids front-end JavaScript libraries with known vulnerabilities', () => { @@ -100,22 +101,36 @@ describe('Avoids front-end JavaScript libraries with known vulnerabilities', () }); }); +// https://github.com/npm/node-semver/issues/166#issuecomment-245990039 +function hasUpperBound(rangeString) { + const range = new semver.Range(rangeString); + if (!range) return false; + + for (const subset of range.set) { + // Upperbound exists if... + + // < or <= is in one of the subset's clauses (= gets normalized to >= and <). + if (subset.some(comparator => comparator.operator.match(/^ { for (const vulns of Object.values(NoVulnerableLibrariesAudit.snykDB.npm)) { for (const vuln of vulns) { for (const semver of vuln.semver.vulnerable) { - // Examples of what semver can be: - // <1.12.2 - // >=1.12.3 <2.2.2 - // >=2.2.3 <3.0.0 - // >=3.0.0 <3.10.1 || =3.10.2 - assert.notEqual(semver, '*', 'invalid semver: * is not allowed'); - - const clauses = semver.split('||'); - for (const clause of clauses) { - if (!clause.trim().startsWith('=') && !clause.includes('<')) { - assert.fail(`invalid semver: ${semver}. Must contain an upper bound`); - } + if (!hasUpperBound(semver)) { + assert.fail(`invalid semver: ${semver}. Must contain an upper bound`); } } } From 55bf357da7aa48a25dc7c9fbd47722fbd66c03da Mon Sep 17 00:00:00 2001 From: Connor Clark Date: Mon, 8 Jul 2019 18:04:55 -0700 Subject: [PATCH 7/8] comments --- .../test/audits/dobetterweb/no-vulnerable-libraries-test.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lighthouse-core/test/audits/dobetterweb/no-vulnerable-libraries-test.js b/lighthouse-core/test/audits/dobetterweb/no-vulnerable-libraries-test.js index c1aaf719f58c..3faeba2488d3 100644 --- a/lighthouse-core/test/audits/dobetterweb/no-vulnerable-libraries-test.js +++ b/lighthouse-core/test/audits/dobetterweb/no-vulnerable-libraries-test.js @@ -106,6 +106,7 @@ function hasUpperBound(rangeString) { const range = new semver.Range(rangeString); if (!range) return false; + // For every subset ... for (const subset of range.set) { // Upperbound exists if... @@ -119,6 +120,7 @@ function hasUpperBound(rangeString) { continue; } + // No upperbound for this subset. return false; } From 4653ba138ae54e9d46eaa995fc4042a8c35671e9 Mon Sep 17 00:00:00 2001 From: Connor Clark Date: Wed, 10 Jul 2019 14:27:26 -0700 Subject: [PATCH 8/8] update --- .../no-vulnerable-libraries-test.js | 62 ++++++++++++------- 1 file changed, 38 insertions(+), 24 deletions(-) diff --git a/lighthouse-core/test/audits/dobetterweb/no-vulnerable-libraries-test.js b/lighthouse-core/test/audits/dobetterweb/no-vulnerable-libraries-test.js index 3faeba2488d3..33f1c60fe794 100644 --- a/lighthouse-core/test/audits/dobetterweb/no-vulnerable-libraries-test.js +++ b/lighthouse-core/test/audits/dobetterweb/no-vulnerable-libraries-test.js @@ -101,40 +101,54 @@ describe('Avoids front-end JavaScript libraries with known vulnerabilities', () }); }); -// https://github.com/npm/node-semver/issues/166#issuecomment-245990039 -function hasUpperBound(rangeString) { - const range = new semver.Range(rangeString); - if (!range) return false; - - // For every subset ... - for (const subset of range.set) { +describe('Snyk database', () => { + // https://github.com/npm/node-semver/issues/166#issuecomment-245990039 + function hasUpperBound(rangeString) { + const range = new semver.Range(rangeString); + if (!range) return false; + + // For every subset ... + for (const subset of range.set) { // Upperbound exists if... // < or <= is in one of the subset's clauses (= gets normalized to >= and <). - if (subset.some(comparator => comparator.operator.match(/^ comparator.operator && comparator.operator.match(/^ { + assert.equal(hasUpperBound('<1.12.2'), true); + assert.equal(hasUpperBound('=1.12.2'), true); + assert.equal(hasUpperBound('>=1.12.3 <2.2.2'), true); + assert.equal(hasUpperBound('>=2.2.3 <3.0.0'), true); + assert.equal(hasUpperBound('>=3.0.0 <3.10.1 || =3.10.2'), true); -describe('every snyk vulnerability has an upper bound', () => { - for (const vulns of Object.values(NoVulnerableLibrariesAudit.snykDB.npm)) { - for (const vuln of vulns) { - for (const semver of vuln.semver.vulnerable) { - if (!hasUpperBound(semver)) { - assert.fail(`invalid semver: ${semver}. Must contain an upper bound`); + assert.equal(hasUpperBound('>1.12.2'), false); + assert.equal(hasUpperBound('>=1.12.2'), false); + assert.equal(hasUpperBound('*'), false); + }); + + it('every snyk vulnerability has an upper bound', () => { + for (const vulns of Object.values(NoVulnerableLibrariesAudit.snykDB.npm)) { + for (const vuln of vulns) { + for (const semver of vuln.semver.vulnerable) { + if (!hasUpperBound(semver)) { + assert.fail(`invalid semver: ${semver}. Must contain an upper bound`); + } } } } - } + }); });