UNPKG

snyk-policy

Version:

Snyk's policy parser and matching logic

357 lines (318 loc) 10.7 kB
/// <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 { }