|
8 | 8 | const NoVulnerableLibrariesAudit = |
9 | 9 | require('../../../audits/dobetterweb/no-vulnerable-libraries.js'); |
10 | 10 | const assert = require('assert'); |
| 11 | +const semver = require('semver'); |
11 | 12 |
|
12 | 13 | /* eslint-env jest */ |
13 | 14 | describe('Avoids front-end JavaScript libraries with known vulnerabilities', () => { |
@@ -99,3 +100,55 @@ describe('Avoids front-end JavaScript libraries with known vulnerabilities', () |
99 | 100 | assert.equal(auditResult.score, 1); |
100 | 101 | }); |
101 | 102 | }); |
| 103 | + |
| 104 | +describe('Snyk database', () => { |
| 105 | + // https://github.com/npm/node-semver/issues/166#issuecomment-245990039 |
| 106 | + function hasUpperBound(rangeString) { |
| 107 | + const range = new semver.Range(rangeString); |
| 108 | + if (!range) return false; |
| 109 | + |
| 110 | + // For every subset ... |
| 111 | + for (const subset of range.set) { |
| 112 | + // Upperbound exists if... |
| 113 | + |
| 114 | + // < or <= is in one of the subset's clauses (= gets normalized to >= and <). |
| 115 | + if (subset.some(comparator => comparator.operator && comparator.operator.match(/^</))) { |
| 116 | + continue; |
| 117 | + } |
| 118 | + |
| 119 | + // Subset has a prerelease tag (operator will be empty string). |
| 120 | + if (subset.length === 1 && subset[0].operator === '') { |
| 121 | + continue; |
| 122 | + } |
| 123 | + |
| 124 | + // No upperbound for this subset. |
| 125 | + return false; |
| 126 | + } |
| 127 | + |
| 128 | + return true; |
| 129 | + } |
| 130 | + |
| 131 | + it('hasUpperBound works as intended', () => { |
| 132 | + assert.equal(hasUpperBound('<1.12.2'), true); |
| 133 | + assert.equal(hasUpperBound('=1.12.2'), true); |
| 134 | + assert.equal(hasUpperBound('>=1.12.3 <2.2.2'), true); |
| 135 | + assert.equal(hasUpperBound('>=2.2.3 <3.0.0'), true); |
| 136 | + assert.equal(hasUpperBound('>=3.0.0 <3.10.1 || =3.10.2'), true); |
| 137 | + |
| 138 | + assert.equal(hasUpperBound('>1.12.2'), false); |
| 139 | + assert.equal(hasUpperBound('>=1.12.2'), false); |
| 140 | + assert.equal(hasUpperBound('*'), false); |
| 141 | + }); |
| 142 | + |
| 143 | + it('every snyk vulnerability has an upper bound', () => { |
| 144 | + for (const vulns of Object.values(NoVulnerableLibrariesAudit.snykDB.npm)) { |
| 145 | + for (const vuln of vulns) { |
| 146 | + for (const semver of vuln.semver.vulnerable) { |
| 147 | + if (!hasUpperBound(semver)) { |
| 148 | + assert.fail(`invalid semver: ${semver}. Must contain an upper bound`); |
| 149 | + } |
| 150 | + } |
| 151 | + } |
| 152 | + } |
| 153 | + }); |
| 154 | +}); |
0 commit comments