snyk-policy
Version:
Snyk's policy parser and matching logic
357 lines (318 loc) • 10.7 kB
TypeScript
/// <reference types="node" />
export declare interface AddRuleOptions extends Rule {
/**
* The id of the vulnerability to which the rule applies.
*/
id: string;
/**
* The path or the dependency to which the rule applies.
*/
path: string;
ignoredBy?: {
email: string;
};
patched?: string;
reasonType?: ReasonType;
}
/**
* Type of a function returning the root of a vulnerability URL
*/
export declare type ApiRootFunction = (vulnId: string) => string;
/** Returns an empty policy */
export declare const create: () => Promise<Policy>;
/**
* Demunges the given policy object.
* @param policy The policy object to demunge
* @param apiRoot A string or func calculating the base URL for the Snyk API
* @returns The demunged policy object
*/
export declare function demunge(policy: Policy, apiRoot?: ApiRootFunction | string): DemungedResults;
export declare interface DemungedResults {
exclude: VulnRules[];
ignore: VulnRules[];
patch: VulnRules[];
version: string;
}
export declare type ExcludeRuleSet = Record<PatternGroup, (string | PathObj)[]>;
export declare interface FilteredRule extends Rule {
path: string[];
}
export declare type FilteredVulnerability<T extends Vulnerability = Vulnerability> = T & {
filtered?: {
ignored?: FilteredRule[];
patches?: FilteredRule[];
};
note?: string;
};
export declare interface FilteredVulnerabilityReport<T extends Vulnerability = Vulnerability> {
ok: boolean;
vulnerabilities: FilteredVulnerability<T>[];
filtered: {
ignore: Vulnerability[];
patch: Vulnerability[];
};
}
/**
* Returns any matching rule given a specific vulnerability object. The `vuln` object must contain
* `id` and `from` to match correctly.
* @param policy the policy object to apply to the vulnerabilities
* @param vuln a single vulnerability, where `from` contains the dependency path in which it was introduced
* @returns the matching rule, or null if no match was found
*/
export declare function getByVuln(policy?: Policy, vuln?: Vulnerability): VulnRule | null;
/**
* Returns true if the error is a NodeJS error.
* @param value The value to check.
*/
export declare function isNodeError(value: unknown): value is NodeJS.ErrnoException;
/**
* Returns true if the value is an object. This is a more reliable check than `typeof` or
* `instanceof`, because `typeof null` is `object` and `typeof []` is `object` which is not what
* we want.
* @param v The value to check.
* @returns True if the value is an object.
*/
export declare function isObject(v: unknown): v is Record<string, unknown>;
/**
* Loads a policy from disk. If `root` is an array of strings, the policies will be merged together.
* @param root the root directory to load the policy from (default is `process.cwd())`
* @param options options for loading the policy or policies
* @returns a single policy if `root` is a string, or a merged policy if `root` is an array of strings
*/
export declare function load(root?: string | string[] | loadOptions, options?: loadOptions): Promise<Policy>;
/**
* Loads a policy from text
* @param text the policy text
* @returns the policy
*/
export declare function loadFromText(text?: string): Promise<Policy>;
declare interface loadOptions {
loose?: boolean;
'ignore-policy'?: boolean;
'trust-policies'?: boolean;
}
export declare type MatchStrategy = 'packageManager' | 'exact';
/**
* Returns whether any of the rule paths match the path in which the vulnerability was introduced.
* @param vuln a single vulnerability, where `from` contains the dependency path in which it was introduced
* @param rule an ignore rule for the given vulnerability with one or more paths to ignore
* @param matchStrategy the strategy used to match vulnerabilities (defaults to 'packageManager')
* @returns whether any ignore rules match the vulnerabilities import path
*/
export declare function matchToRule(vuln: {
id?: string;
from: string[];
}, pathObj: PathObj, matchStrategy?: MatchStrategy): boolean;
export declare interface MetaRule extends Rule {
path: string[] | {
module: string;
url?: string;
}[];
}
/**
* A dependency package.
*/
export declare interface Package {
name: string;
version: string;
}
/**
* @example
* {
* "urls": [
* "https://raw.githubusercontent.com/Snyk/vulndb/snapshots/master/patches/npm/handlebars/20151207/handlebars_0.patch"
* ],
* "version": "<4.0.0 >=3.0.2",
* "modificationTime": "2015-12-14T23:52:16.811Z",
* "comments": [
* "https://github.com/wycats/handlebars.js/commit/83b8e846a3569bd366cf0b6bdc1e4604d1a2077e"
* ],
* "id": "patch:npm:handlebars:20151207:0"
* }
*/
declare interface Patch {
urls?: string[];
version?: string;
modificationTime: string;
comments?: string[];
id: string;
}
export declare interface PatchMetaData {
patched: string;
}
/**
* @example
* {
* "sqlite > sqlite3 > node-pre-gyp > request > hawk": {
* "reason": "None given",
* "expires": "2016-03-01T14:30:04.136Z"
* }
* }
*/
export declare type PathObj = Record<string, Rule>;
export declare type PathRule = {
/**
* The path to which the rule is applied.
*/
path: string;
/**
* If true, the rule is disregarded if the vulnerability is fixable.
*/
disregardIfFixable?: boolean;
/**
* The date the rule expires.
*/
expires?: Date;
/**
* The reason for the rule.
*/
reason?: string;
};
export declare type PatternGroup = 'global' | 'code' | 'iac-drift';
export declare interface Policy {
__filename: string | null;
__created: Date | number;
__modified: Date | number;
ignore: RuleSet;
patch: RuleSet;
suggest: RuleSet;
exclude?: ExcludeRuleSet;
failThreshold: Severity;
skipVerifyPatch: boolean;
version: string;
add: (type: 'ignore' | 'patch', options: AddRuleOptions) => Policy;
addExclude: (pattern: string, group?: PatternGroup, options?: Rule) => void;
addIgnore: (options: AddRuleOptions) => Policy;
addPatch: (options: AddRuleOptions) => Policy;
demunge: (apiRoot?: ApiRootFunction | string) => DemungedResults;
filter: <VulnType extends Vulnerability, ReportType>(vulns: ReportType & VulnerabilityReport<VulnType>, root?: string, matchStrategy?: MatchStrategy) => ReportType & FilteredVulnerabilityReport<VulnType>;
save: (root?: string | undefined, spinner?: Spinner) => Promise<void>;
}
export declare class PolicyError extends Error {
code?: string;
constructor(message: string, code?: string);
}
export declare type ReasonType = 'not-vulnerable' | 'wont-fix' | 'temporary-ignore';
/**
* @example
* {
* "reason": "None given",
* "expires": "2016-03-01T14:30:04.136Z"
* }
*/
export declare interface Rule {
created?: Date;
disregardIfFixable?: boolean;
expires?: string | Date;
ignoredBy?: {
email?: string;
name?: string;
};
reason?: string;
reasonType?: ReasonType;
source?: string;
from?: string;
}
/**
* @example
* {
* "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"
* }
* }
* ],
* }
*/
export declare type RuleSet = Record<string, PathObj[]>;
/**
* Saves a policy to disk.
* @param object the policy to save
* @param root the root directory to save the policy to (default is `process.cwd())`
* @param spinner a progress indicator, as used in the [Snyk CLI](https://github.com/Snyk/snyk-internal/blob/0459a7b21709c6a1d3c5edeb61b4abf2103ffaf0/cli/commands/protect/wizard.js#L268)
* @returns the result of `spinner.clear()`
*/
export declare function save(object: Policy, root?: string, spinner?: Spinner): Promise<any>;
export declare interface SecurityPolicyMetaData {
ignore?: MetaRule;
}
/**
* Vulnerability severity.
*/
export declare type Severity = 'critical' | 'high' | 'medium' | 'low';
export declare type Spinner = {
(label: string): Promise<any>;
clear: (label: string) => Promise<any>;
};
export declare interface Vulnerability {
__filename?: string;
readonly id: string;
severity?: Severity;
/**
* The dependency path in which the vulnerability was introduced. A chain of the packages leading
* to the culprit, in the `name` or `name@version` format.This should include the project
* itself.
* The element [0] is the root package (the scanned project). The element [1] is a top-level
* dependency etc.
*/
from: string[];
isUpgradable?: boolean;
/**
* A possible upgrade remediation path. Mirrors the `from` field above, but contains upgraded
* versions. The element [0] is usually `false` and is of no use. If the element [1] is false,
* there's no valid complete upgrade path yet.
*/
upgradePath?: (string | boolean)[];
isPatchable?: boolean;
patches?: Patch[];
securityPolicyMetaData?: SecurityPolicyMetaData;
}
export declare interface VulnerabilityReport<T extends Vulnerability = Vulnerability> {
/**
* If all the vulns are stripped because of the policy, then the `ok` bool is set to `true`.
*/
ok?: boolean;
/**
* The vulnerabilities found in the project.
*/
vulnerabilities: T[];
}
export declare interface VulnRule extends Rule {
/**
* The vulnerability ID.
*/
id: string;
/**
* The type of rule.
*/
type: 'ignore' | 'patch';
/**
* An array of dependencies (`package@version`) in which the vulnerability was introduced.
*/
rule: Array<string>;
}
export declare interface VulnRules {
/**
* The vulnerability ID.
*/
id: string;
/**
* The URL to the vulnerability on the Snyk website.
*/
url: string;
/**
* The vulnerability's rules with paths to ignore.
*/
paths: PathRule[];
}
export { }