@fabasoad/sarif-to-slack 0.2.2 → 0.2.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,3 +1,19 @@
1
+ /**
2
+ * This function finds the respective tool for the given result.
3
+ * @param run An instance of {@link Run} object.
4
+ * @param result An instance of {@link Result} object.
5
+ * @internal
6
+ */
7
+ export function findToolComponentByResult(run, result) {
8
+ let tool;
9
+ if (result?.rule?.toolComponent?.index != null) {
10
+ tool = run.tool.extensions?.[result.rule.toolComponent.index];
11
+ }
12
+ if (!tool) {
13
+ tool = run.tool.driver;
14
+ }
15
+ return tool;
16
+ }
1
17
  /**
2
18
  * This function tries to find the respective rule for the given result.
3
19
  * @param run An instance of {@link Run} object.
@@ -7,24 +23,28 @@
7
23
  export function findRuleByResult(run, result) {
8
24
  const ruleData = {};
9
25
  if (result.rule) {
10
- if (result.rule?.index) {
26
+ if (result.rule?.index != null) {
11
27
  ruleData.index = result.rule.index;
12
28
  }
13
29
  if (result.rule?.id) {
14
30
  ruleData.id = result.rule.id;
15
31
  }
16
32
  }
17
- if (!ruleData.index && result.ruleIndex) {
33
+ if (ruleData.index == null && result.ruleIndex != null) {
18
34
  ruleData.index = result.ruleIndex;
19
35
  }
20
- if (ruleData.index
21
- && run.tool.driver?.rules
22
- && ruleData.index < run.tool.driver.rules.length) {
23
- return run.tool.driver.rules[ruleData.index];
36
+ if (!ruleData.id && result.ruleId) {
37
+ ruleData.id = result.ruleId;
38
+ }
39
+ const tool = findToolComponentByResult(run, result);
40
+ if (ruleData.index != null
41
+ && tool?.rules
42
+ && ruleData.index < tool.rules.length) {
43
+ return tool.rules[ruleData.index];
24
44
  }
25
45
  // If failed to find rule by index then try to find by ruleId
26
- if (result.ruleId && run.tool.driver?.rules) {
27
- return run.tool.driver.rules.find((r) => r.id === result.ruleId);
46
+ if (ruleData.id && tool?.rules) {
47
+ return tool.rules.find((r) => r.id === ruleData.id);
28
48
  }
29
49
  return undefined;
30
50
  }
@@ -43,4 +63,4 @@ export function tryGetRulePropertyByResult(run, result, propertyName) {
43
63
  }
44
64
  return undefined;
45
65
  }
46
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiU2FyaWZVdGlscy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy91dGlscy9TYXJpZlV0aWxzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUVBOzs7OztHQUtHO0FBQ0gsTUFBTSxVQUFVLGdCQUFnQixDQUFDLEdBQVEsRUFBRSxNQUFjO0lBQ3ZELE1BQU0sUUFBUSxHQUFvQyxFQUFFLENBQUE7SUFFcEQsSUFBSSxNQUFNLENBQUMsSUFBSSxFQUFFLENBQUM7UUFDaEIsSUFBSSxNQUFNLENBQUMsSUFBSSxFQUFFLEtBQUssRUFBRSxDQUFDO1lBQ3ZCLFFBQVEsQ0FBQyxLQUFLLEdBQUcsTUFBTSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUE7UUFDcEMsQ0FBQztRQUNELElBQUksTUFBTSxDQUFDLElBQUksRUFBRSxFQUFFLEVBQUUsQ0FBQztZQUNwQixRQUFRLENBQUMsRUFBRSxHQUFHLE1BQU0sQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFBO1FBQzlCLENBQUM7SUFDSCxDQUFDO0lBRUQsSUFBSSxDQUFDLFFBQVEsQ0FBQyxLQUFLLElBQUksTUFBTSxDQUFDLFNBQVMsRUFBRSxDQUFDO1FBQ3hDLFFBQVEsQ0FBQyxLQUFLLEdBQUcsTUFBTSxDQUFDLFNBQVMsQ0FBQTtJQUNuQyxDQUFDO0lBRUQsSUFBSSxRQUFRLENBQUMsS0FBSztXQUNiLEdBQUcsQ0FBQyxJQUFJLENBQUMsTUFBTSxFQUFFLEtBQUs7V0FDdEIsUUFBUSxDQUFDLEtBQUssR0FBRyxHQUFHLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsTUFBTSxFQUFFLENBQUM7UUFDbkQsT0FBTyxHQUFHLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQyxDQUFBO0lBQzlDLENBQUM7SUFFRCw2REFBNkQ7SUFDN0QsSUFBSSxNQUFNLENBQUMsTUFBTSxJQUFJLEdBQUcsQ0FBQyxJQUFJLENBQUMsTUFBTSxFQUFFLEtBQUssRUFBRSxDQUFDO1FBQzVDLE9BQU8sR0FBRyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLElBQUksQ0FDL0IsQ0FBQyxDQUFzQixFQUFXLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBRSxLQUFLLE1BQU0sQ0FBQyxNQUFNLENBQzVELENBQUE7SUFDSCxDQUFDO0lBRUQsT0FBTyxTQUFTLENBQUE7QUFDbEIsQ0FBQztBQVFEOzs7Ozs7O0dBT0c7QUFDSCxNQUFNLFVBQVUsMEJBQTBCLENBQUksR0FBUSxFQUFFLE1BQWMsRUFBRSxZQUEwQjtJQUNoRyxNQUFNLElBQUksR0FBb0MsZ0JBQWdCLENBQUMsR0FBRyxFQUFFLE1BQU0sQ0FBQyxDQUFBO0lBQzNFLElBQUksSUFBSSxJQUFJLElBQUksQ0FBQyxVQUFVLElBQUksWUFBWSxJQUFJLElBQUksQ0FBQyxVQUFVLEVBQUUsQ0FBQztRQUMvRCxPQUFPLElBQUksQ0FBQyxVQUFVLENBQUMsWUFBWSxDQUFNLENBQUE7SUFDM0MsQ0FBQztJQUVELE9BQU8sU0FBUyxDQUFBO0FBQ2xCLENBQUMifQ==
66
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiU2FyaWZVdGlscy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy91dGlscy9TYXJpZlV0aWxzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUVBOzs7OztHQUtHO0FBQ0gsTUFBTSxVQUFVLHlCQUF5QixDQUFDLEdBQVEsRUFBRSxNQUFlO0lBQ2pFLElBQUksSUFBK0IsQ0FBQTtJQUNuQyxJQUFJLE1BQU0sRUFBRSxJQUFJLEVBQUUsYUFBYSxFQUFFLEtBQUssSUFBSSxJQUFJLEVBQUUsQ0FBQztRQUMvQyxJQUFJLEdBQUcsR0FBRyxDQUFDLElBQUksQ0FBQyxVQUFVLEVBQUUsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxLQUFLLENBQUMsQ0FBQTtJQUMvRCxDQUFDO0lBRUQsSUFBSSxDQUFDLElBQUksRUFBRSxDQUFDO1FBQ1YsSUFBSSxHQUFHLEdBQUcsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFBO0lBQ3hCLENBQUM7SUFFRCxPQUFPLElBQUksQ0FBQTtBQUNiLENBQUM7QUFFRDs7Ozs7R0FLRztBQUNILE1BQU0sVUFBVSxnQkFBZ0IsQ0FBQyxHQUFRLEVBQUUsTUFBYztJQUN2RCxNQUFNLFFBQVEsR0FBb0MsRUFBRSxDQUFBO0lBRXBELElBQUksTUFBTSxDQUFDLElBQUksRUFBRSxDQUFDO1FBQ2hCLElBQUksTUFBTSxDQUFDLElBQUksRUFBRSxLQUFLLElBQUksSUFBSSxFQUFFLENBQUM7WUFDL0IsUUFBUSxDQUFDLEtBQUssR0FBRyxNQUFNLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQTtRQUNwQyxDQUFDO1FBQ0QsSUFBSSxNQUFNLENBQUMsSUFBSSxFQUFFLEVBQUUsRUFBRSxDQUFDO1lBQ3BCLFFBQVEsQ0FBQyxFQUFFLEdBQUcsTUFBTSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUE7UUFDOUIsQ0FBQztJQUNILENBQUM7SUFFRCxJQUFJLFFBQVEsQ0FBQyxLQUFLLElBQUksSUFBSSxJQUFJLE1BQU0sQ0FBQyxTQUFTLElBQUksSUFBSSxFQUFFLENBQUM7UUFDdkQsUUFBUSxDQUFDLEtBQUssR0FBRyxNQUFNLENBQUMsU0FBUyxDQUFBO0lBQ25DLENBQUM7SUFFRCxJQUFJLENBQUMsUUFBUSxDQUFDLEVBQUUsSUFBSSxNQUFNLENBQUMsTUFBTSxFQUFFLENBQUM7UUFDbEMsUUFBUSxDQUFDLEVBQUUsR0FBRyxNQUFNLENBQUMsTUFBTSxDQUFBO0lBQzdCLENBQUM7SUFFRCxNQUFNLElBQUksR0FBa0IseUJBQXlCLENBQUMsR0FBRyxFQUFFLE1BQU0sQ0FBQyxDQUFBO0lBRWxFLElBQUksUUFBUSxDQUFDLEtBQUssSUFBSSxJQUFJO1dBQ3JCLElBQUksRUFBRSxLQUFLO1dBQ1gsUUFBUSxDQUFDLEtBQUssR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLE1BQU0sRUFBRSxDQUFDO1FBQ3hDLE9BQU8sSUFBSSxDQUFDLEtBQUssQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLENBQUE7SUFDbkMsQ0FBQztJQUVELDZEQUE2RDtJQUM3RCxJQUFJLFFBQVEsQ0FBQyxFQUFFLElBQUksSUFBSSxFQUFFLEtBQUssRUFBRSxDQUFDO1FBQy9CLE9BQU8sSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQ3BCLENBQUMsQ0FBc0IsRUFBVyxFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQUUsS0FBSyxRQUFRLENBQUMsRUFBRSxDQUMxRCxDQUFBO0lBQ0gsQ0FBQztJQUVELE9BQU8sU0FBUyxDQUFBO0FBQ2xCLENBQUM7QUFRRDs7Ozs7OztHQU9HO0FBQ0gsTUFBTSxVQUFVLDBCQUEwQixDQUFJLEdBQVEsRUFBRSxNQUFjLEVBQUUsWUFBMEI7SUFDaEcsTUFBTSxJQUFJLEdBQW9DLGdCQUFnQixDQUFDLEdBQUcsRUFBRSxNQUFNLENBQUMsQ0FBQTtJQUMzRSxJQUFJLElBQUksSUFBSSxJQUFJLENBQUMsVUFBVSxJQUFJLFlBQVksSUFBSSxJQUFJLENBQUMsVUFBVSxFQUFFLENBQUM7UUFDL0QsT0FBTyxJQUFJLENBQUMsVUFBVSxDQUFDLFlBQVksQ0FBTSxDQUFBO0lBQzNDLENBQUM7SUFFRCxPQUFPLFNBQVMsQ0FBQTtBQUNsQixDQUFDIn0=
package/dist/version.js CHANGED
@@ -7,5 +7,5 @@
7
7
  *
8
8
  * @internal
9
9
  */
10
- export const LIB_VERSION = '0.2.2';
10
+ export const LIB_VERSION = '0.2.4';
11
11
  //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidmVyc2lvbi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy92ZXJzaW9uLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7OztHQVFHO0FBQ0gsTUFBTSxDQUFDLE1BQU0sV0FBVyxHQUFHLE9BQU8sQ0FBQSJ9
package/jest.config.json CHANGED
@@ -10,7 +10,7 @@
10
10
  ],
11
11
  "coverageThreshold": {
12
12
  "global": {
13
- "branches": 15,
13
+ "branches": 10,
14
14
  "functions": 10,
15
15
  "lines": 15,
16
16
  "statements": 15
package/package.json CHANGED
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "name": "@fabasoad/sarif-to-slack",
3
- "version": "0.2.2",
3
+ "version": "0.2.4",
4
4
  "description": "TypeScript library to send results of SARIF file to Slack webhook URL.",
5
- "main": "dist/index.js",
5
+ "main": "dist/index.cjs",
6
6
  "module": "dist/index.js",
7
7
  "typings": "dist/index.d.ts",
8
8
  "private": false,
@@ -12,9 +12,8 @@
12
12
  "test:integration": "jest --config=jest.config.json --testNamePattern=integration",
13
13
  "clean": "rm -rf coverage && rm -rf temp",
14
14
  "clean:unsafe": "rm -f package-lock.json && rm -rf node_modules && rm -rf dist && rm -rf lib",
15
- "tsc": "tsc",
16
15
  "prebuild": "./scripts/save-version.sh",
17
- "build": "npm run tsc && api-extractor run --local --verbose",
16
+ "build": "./scripts/build.sh",
18
17
  "prepublishOnly": "npm run build",
19
18
  "preinstall": "./scripts/save-version.sh",
20
19
  "version:patch": "npm version patch --commit-hooks --git-tag-version --message 'chore: bump to version %s'",
@@ -56,6 +55,7 @@
56
55
  "jest": "30.0.5",
57
56
  "jest-circus": "30.0.5",
58
57
  "ts-jest": "29.4.0",
58
+ "tsup": "8.5.0",
59
59
  "typescript": "5.8.3"
60
60
  }
61
61
  }
@@ -0,0 +1,11 @@
1
+ #!/usr/bin/env sh
2
+
3
+ main() {
4
+ tsc
5
+ api-extractor run --local --verbose
6
+ tsup src/index.ts --format cjs --target es2024 --out-dir dist-cjs --clean
7
+ mv dist-cjs/index.js dist/index.cjs
8
+ rm -rf dist-cjs
9
+ }
10
+
11
+ main "$@"
@@ -1,5 +1,8 @@
1
1
  import type { Result, Run } from 'sarif';
2
- import { tryGetRulePropertyByResult } from '../utils/SarifUtils'
2
+ import {
3
+ findToolComponentByResult,
4
+ tryGetRulePropertyByResult
5
+ } from '../utils/SarifUtils'
3
6
  import { SecurityLevel, SecuritySeverity } from './types'
4
7
  import Logger from '../Logger'
5
8
  import { Map as ImmutableMap } from 'immutable'
@@ -21,7 +24,7 @@ export class SarifModelPerRun {
21
24
  private readonly _securityLevelMap: ImmutableMap<SecurityLevel, number>
22
25
 
23
26
  constructor(run: Run) {
24
- this.toolName = run.tool.driver.name
27
+ this.toolName = findToolComponentByResult(run, run.results?.[0]).name
25
28
 
26
29
  this._securitySeverityMap = ImmutableMap<SecuritySeverity, number>().asMutable()
27
30
  this._securityLevelMap = ImmutableMap<SecurityLevel, number>().asMutable()
@@ -1,4 +1,23 @@
1
- import type { ReportingDescriptor, Result, Run } from "sarif";
1
+ import type { ReportingDescriptor, Result, Run, ToolComponent } from "sarif";
2
+
3
+ /**
4
+ * This function finds the respective tool for the given result.
5
+ * @param run An instance of {@link Run} object.
6
+ * @param result An instance of {@link Result} object.
7
+ * @internal
8
+ */
9
+ export function findToolComponentByResult(run: Run, result?: Result): ToolComponent {
10
+ let tool: ToolComponent | undefined
11
+ if (result?.rule?.toolComponent?.index != null) {
12
+ tool = run.tool.extensions?.[result.rule.toolComponent.index]
13
+ }
14
+
15
+ if (!tool) {
16
+ tool = run.tool.driver
17
+ }
18
+
19
+ return tool
20
+ }
2
21
 
3
22
  /**
4
23
  * This function tries to find the respective rule for the given result.
@@ -10,7 +29,7 @@ export function findRuleByResult(run: Run, result: Result): ReportingDescriptor
10
29
  const ruleData: { id?: string, index?: number } = {}
11
30
 
12
31
  if (result.rule) {
13
- if (result.rule?.index) {
32
+ if (result.rule?.index != null) {
14
33
  ruleData.index = result.rule.index
15
34
  }
16
35
  if (result.rule?.id) {
@@ -18,20 +37,26 @@ export function findRuleByResult(run: Run, result: Result): ReportingDescriptor
18
37
  }
19
38
  }
20
39
 
21
- if (!ruleData.index && result.ruleIndex) {
40
+ if (ruleData.index == null && result.ruleIndex != null) {
22
41
  ruleData.index = result.ruleIndex
23
42
  }
24
43
 
25
- if (ruleData.index
26
- && run.tool.driver?.rules
27
- && ruleData.index < run.tool.driver.rules.length) {
28
- return run.tool.driver.rules[ruleData.index]
44
+ if (!ruleData.id && result.ruleId) {
45
+ ruleData.id = result.ruleId
46
+ }
47
+
48
+ const tool: ToolComponent = findToolComponentByResult(run, result)
49
+
50
+ if (ruleData.index != null
51
+ && tool?.rules
52
+ && ruleData.index < tool.rules.length) {
53
+ return tool.rules[ruleData.index]
29
54
  }
30
55
 
31
56
  // If failed to find rule by index then try to find by ruleId
32
- if (result.ruleId && run.tool.driver?.rules) {
33
- return run.tool.driver.rules.find(
34
- (r: ReportingDescriptor): boolean => r.id === result.ruleId
57
+ if (ruleData.id && tool?.rules) {
58
+ return tool.rules.find(
59
+ (r: ReportingDescriptor): boolean => r.id === ruleData.id
35
60
  )
36
61
  }
37
62
 
package/src/version.ts CHANGED
@@ -7,4 +7,4 @@
7
7
  *
8
8
  * @internal
9
9
  */
10
- export const LIB_VERSION = '0.2.2'
10
+ export const LIB_VERSION = '0.2.4'
@@ -0,0 +1,24 @@
1
+ {
2
+ "$schema": "https://raw.githubusercontent.com/oasis-tcs/sarif-spec/master/Schemata/sarif-schema-2.1.0.json",
3
+ "version": "2.1.0",
4
+ "runs": [
5
+ {
6
+ "tool": {
7
+ "driver": {
8
+ "language": "en-US",
9
+ "name": "Snyk Open Source"
10
+ },
11
+ "extensions": [
12
+ {
13
+ "name": "Snyk Open Source Extension",
14
+ "properties": {
15
+ "artifactsScanned": 6
16
+ },
17
+ "rules": []
18
+ }
19
+ ]
20
+ },
21
+ "results": []
22
+ }
23
+ ]
24
+ }
@@ -0,0 +1,79 @@
1
+ {
2
+ "$schema": "https://raw.githubusercontent.com/oasis-tcs/sarif-spec/master/Schemata/sarif-schema-2.1.0.json",
3
+ "version": "2.1.0",
4
+ "runs": [
5
+ {
6
+ "tool": {
7
+ "driver": {
8
+ "language": "en-US",
9
+ "name": "Snyk Open Source"
10
+ },
11
+ "extensions": [
12
+ {
13
+ "name": "Snyk Open Source Extension",
14
+ "properties": {
15
+ "artifactsScanned": 6
16
+ },
17
+ "rules": [
18
+ {
19
+ "id": "SNYK-HEX-PAGINATOR-1086684",
20
+ "shortDescription": {
21
+ "text": "Critical severity - Remote Code Execution (RCE) vulnerability in paginator"
22
+ },
23
+ "fullDescription": {
24
+ "text": "(CVE-2020-15150) paginator@0.6.0"
25
+ },
26
+ "help": {
27
+ "text": "",
28
+ "markdown": "* Package Manager: hex\n* Vulnerable module: paginator\n* Introduced through: carafe@0.1.0 and paginator@0.6.0\n### Detailed paths\n* _Introduced through_: carafe@0.1.0 › paginator@0.6.0\n# Overview\n[paginator](https://hex.pm/packages/paginator) is a package that enables cursor-based pagination for Elixir Ecto.\n\nAffected versions of this package are vulnerable to Remote Code Execution (RCE) via `paginate()` function when untrusted input is passed from a remote user.\r\n\r\n# PoC\r\n```\r\ndefp rce_start_xcalc() do\r\n exploit = fn _, _ -> System.cmd(\"xcalc\", []); {:cont, []} end\r\n payload =\r\n exploit\r\n |> :erlang.term_to_binary()\r\n |> Base.url_encode64()\r\nend\r\n```\n# Remediation\nUpgrade `paginator` to version 1.0.0 or higher.\n# References\n- [GitHub PR](https://github.com/duffelhq/paginator/commit/bf45e92602e517c75aea0465efc35cd661d9ebf8)\n- [Research Blog Post](https://www.alphabot.com/security/blog/2020/elixir/Remote-code-execution-vulnerability-in-Elixir-based-Paginator-project.html)\n"
29
+ },
30
+ "properties": {
31
+ "tags": [
32
+ "security",
33
+ "CWE-94",
34
+ "hex"
35
+ ],
36
+ "cvssv3_baseScore": 9.8,
37
+ "security-severity": "9.8"
38
+ }
39
+ }
40
+ ]
41
+ }
42
+ ]
43
+ },
44
+ "results": [
45
+ {
46
+ "rule": {
47
+ "id": "SNYK-HEX-PAGINATOR-1086684",
48
+ "index": 0,
49
+ "toolComponent": {
50
+ "index": 0
51
+ }
52
+ },
53
+ "ruleId": "SNYK-HEX-PAGINATOR-1086684",
54
+ "level": "error",
55
+ "message": {
56
+ "text": "This file introduces a vulnerable paginator package with a critical severity vulnerability."
57
+ },
58
+ "locations": [
59
+ {
60
+ "physicalLocation": {
61
+ "artifactLocation": {
62
+ "uri": "mix.exs"
63
+ },
64
+ "region": {
65
+ "startLine": 1
66
+ }
67
+ },
68
+ "logicalLocations": [
69
+ {
70
+ "fullyQualifiedName": "paginator@0.6.0"
71
+ }
72
+ ]
73
+ }
74
+ ]
75
+ }
76
+ ]
77
+ }
78
+ ]
79
+ }