Skip to content

Commit

Permalink
feat: support security policies ignore action
Browse files Browse the repository at this point in the history
  • Loading branch information
vasser committed Jun 13, 2021
1 parent cc835cc commit 514cfae
Show file tree
Hide file tree
Showing 7 changed files with 818 additions and 41 deletions.
133 changes: 92 additions & 41 deletions lib/filter/ignore.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,59 +21,92 @@ function filterIgnored(ignore, vuln, filtered) {

return vuln
.map(function (vuln) {
if (!ignore[vuln.id]) {
if (!ignore[vuln.id] && !isSecurityPolicyRuleValid(vuln)) {
return vuln;
}

debug('%s has rules', vuln.id);

// logic: loop through all rules (from `ignore[vuln.id]`), and if *any* dep
// paths match our vuln.from dep chain AND the rule hasn't expired, then the
// vulnerability is ignored. if none of the rules match, then let we'll
// keep it.

// if rules.find, then ignore vuln
const appliedRules = ignore[vuln.id].filter(function (rule) {
const path = Object.keys(rule)[0]; // this is a string
let expires = rule[path].expires;

if (expires && expires.toJSON) {
expires = expires.toJSON();
}
let appliedRules = [];

if (isSecurityPolicyRuleValid(vuln)) {
// logic: if vuln has securityPolicyMetaData.ignore rule, that means it comes
// after security rule applied with the ignore action, thus we have to apply
// this ignore and not any others.
// Security policies ignores we apply to all paths "*" and disregardIfFixable=false
const rule = vuln.securityPolicyMetaData.ignore;

const {
created,
disregardIfFixable,
ignoredBy,
path,
reason = '',
reasonType,
source,
} = rule;

appliedRules = [
{
[path[0]]: {
reason,
reasonType,
source,
ignoredBy,
created,
disregardIfFixable,
},
},
];
} else {
// logic: loop through all rules (from `ignore[vuln.id]`), and if *any* dep
// paths match our vuln.from dep chain AND the rule hasn't expired, then the
// vulnerability is ignored. if none of the rules match, then let we'll
// keep it.

// if rules.find, then ignore vuln
appliedRules = ignore[vuln.id].filter(function (rule) {
const path = Object.keys(rule)[0]; // this is a string
let expires = rule[path].expires;

if (expires && expires.toJSON) {
expires = expires.toJSON();
}

// first check if the path is a match on the rule
const pathMatch = matchToRule(vuln, rule);
// first check if the path is a match on the rule
const pathMatch = matchToRule(vuln, rule);

if (pathMatch && expires && expires < now) {
debug('%s vuln rule has expired (%s)', vuln.id, expires);
return false;
}

if (
pathMatch &&
rule[path].disregardIfFixable &&
(vuln.isUpgradable || vuln.isPatchable)
) {
debug(
'%s vuln is fixable and rule is set to disregard if fixable',
vuln.id
);
return false;
}
if (pathMatch && expires && expires < now) {
debug('%s vuln rule has expired (%s)', vuln.id, expires);
return false;
}

if (pathMatch) {
if (debug.enabled) {
if (
pathMatch &&
rule[path].disregardIfFixable &&
(vuln.isUpgradable || vuln.isPatchable)
) {
debug(
'ignoring based on path match: %s ~= %s',
path,
vuln.from.slice(1).join(' > ')
'%s vuln is fixable and rule is set to disregard if fixable',
vuln.id
);
return false;
}
return true;
}

return false;
});
if (pathMatch) {
if (debug.enabled) {
debug(
'ignoring based on path match: %s ~= %s',
path,
vuln.from.slice(1).join(' > ')
);
}
return true;
}

return false;
});
}

if (appliedRules.length) {
vuln.filtered = {
Expand All @@ -91,3 +124,21 @@ function filterIgnored(ignore, vuln, filtered) {
})
.filter(Boolean);
}

const isSecurityPolicyRuleValid = (vuln) => {
const rule =
vuln.securityPolicyMetaData && vuln.securityPolicyMetaData.ignore;

if (
rule &&
'reasonType' in rule &&
'created' in rule &&
'disregardIfFixable' in rule &&
'ignoredBy' in rule &&
'path' in rule &&
'source' in rule
) {
return true;
}
return false;
};
25 changes: 25 additions & 0 deletions test/fixtures/ignore-security-policy/.snyk
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# Snyk (https://snyk.io) policy file, patches or ignores known vulnerabilities.
# ignores vulnerabilities until expiry date; change duration by modifying expiry date
ignore:
'npm:hawk:20160119':
- sqlite > sqlite3 > node-pre-gyp > request > hawk:
reason: hawk got bumped
expires: '2116-03-01T14:30:04.136Z'
'npm:is-my-json-valid:20160118':
- sqlite > sqlite3 > node-pre-gyp > request > har-validator > is-my-json-valid:
reason: dev tool
expires: '2116-03-01T14:30:04.136Z'
'npm:tar:20151103':
- sqlite > sqlite3 > node-pre-gyp > tar-pack > tar:
reason: none given
expires: '2116-03-01T14:30:04.137Z'
'npm:method-override:20170927':
- '*':
reason: none given
disregardIfFixable: true
'npm:marked:20170907':
- '*':
reason: none given
disregardIfFixable: true
patch: {}
version: v1.0.0
17 changes: 17 additions & 0 deletions test/fixtures/ignore-security-policy/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"name": "ignore",
"version": "1.0.0",
"description": "",
"main": "index.js",
"dependencies": {
"snyk": "*",
"sqlite": "0.0.2"
},
"devDependencies": {},
"scripts": {
"test": "snyk test && echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC"
}
49 changes: 49 additions & 0 deletions test/fixtures/ignore-security-policy/parsed.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
{
"ignore": {
"npm:hawk:20160119": [
{
"sqlite > sqlite3 > node-pre-gyp > request > hawk": {
"reason": "None given",
"expires": "2016-03-01T14:30:04.136Z"
}
}
],
"npm:is-my-json-valid:20160118": [
{
"sqlite > sqlite3 > node-pre-gyp > request > har-validator > is-my-json-valid": {
"reason": "None given",
"expires": "2016-03-01T14:30:04.136Z"
}
}
],
"npm:tar:20151103": [
{
"sqlite > sqlite3 > node-pre-gyp > tar-pack > tar": {
"reason": "None given",
"expires": "2016-03-01T14:30:04.137Z"
}
}
],
"npm:method-override:20170927": [
{
"*": {
"reason": "none given",
"disregardIfFixable": true
}
}
],
"npm:marked:20170907": [
{
"*": {
"reason": "none given",
"disregardIfFixable": true
}
}
]
},
"version": "v1",
"patch": {},
"__filename": "test/fixtures/ignore/.snyk",
"__modified": "2016-03-07T14:52:42.000Z",
"__created": "2016-03-07T14:25:45.000Z"
}

0 comments on commit 514cfae

Please sign in to comment.