@fabasoad/sarif-to-slack 0.2.3 → 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.
- package/.github/workflows/security.yml +1 -0
- package/.github/workflows/send-sarif-to-slack.yml +6 -0
- package/dist/index.cjs +23 -9
- package/dist/model/SarifModelPerRun.js +3 -3
- package/dist/utils/SarifUtils.js +29 -9
- package/dist/version.js +1 -1
- package/jest.config.json +1 -1
- package/package.json +1 -1
- package/src/model/SarifModelPerRun.ts +5 -2
- package/src/utils/SarifUtils.ts +35 -10
- package/src/version.ts +1 -1
- package/test-data/sarif/runs-1-extensions-1-results-0.sarif +24 -0
- package/test-data/sarif/runs-1-extensions-1.sarif +79 -0
|
@@ -34,6 +34,8 @@ on: # yamllint disable-line rule:truthy
|
|
|
34
34
|
- "Trivy IaC (Error: 1, Note: 1)"
|
|
35
35
|
- "Wiz Container (Error: 12, Warning: 369, Note: 191)"
|
|
36
36
|
- "Wiz IaC (Warning: 5, Note: 5)"
|
|
37
|
+
- "Runs: 1, Extensions: 1, Results: 0"
|
|
38
|
+
- "Runs: 1, Extensions: 1, Results > 0"
|
|
37
39
|
- "Runs: 1, Tools: 1, Results: 0"
|
|
38
40
|
- "Runs: 2, Tools: 1, Results > 0"
|
|
39
41
|
- "Runs: 2, Tools: 1, Results: 0"
|
|
@@ -174,6 +176,10 @@ jobs:
|
|
|
174
176
|
value="wiz-iac.sarif"
|
|
175
177
|
elif [ "${INPUT_SARIF}" = "Runs: 1, Tools: 1, Results: 0" ]; then
|
|
176
178
|
value="runs-1-tools-1-results-0.sarif"
|
|
179
|
+
elif [ "${INPUT_SARIF}" = "Runs: 1, Extensions: 1, Results: 0" ]; then
|
|
180
|
+
value="runs-1-extensions-1-results-0.sarif"
|
|
181
|
+
elif [ "${INPUT_SARIF}" = "Runs: 1, Extensions: 1, Results > 0" ]; then
|
|
182
|
+
value="runs-1-extensions-1.sarif"
|
|
177
183
|
elif [ "${INPUT_SARIF}" = "Runs: 2, Tools: 1, Results > 0" ]; then
|
|
178
184
|
value="runs-2-tools-1.sarif"
|
|
179
185
|
elif [ "${INPUT_SARIF}" = "Runs: 2, Tools: 1, Results: 0" ]; then
|
package/dist/index.cjs
CHANGED
|
@@ -149,31 +149,45 @@ function processSarifPath(sarifPath) {
|
|
|
149
149
|
var import_webhook = require("@slack/webhook");
|
|
150
150
|
|
|
151
151
|
// src/version.ts
|
|
152
|
-
var LIB_VERSION = "0.2.
|
|
152
|
+
var LIB_VERSION = "0.2.4";
|
|
153
153
|
|
|
154
154
|
// src/model/SarifModelPerSarif.ts
|
|
155
155
|
var import_immutable2 = require("immutable");
|
|
156
156
|
|
|
157
157
|
// src/utils/SarifUtils.ts
|
|
158
|
+
function findToolComponentByResult(run, result) {
|
|
159
|
+
let tool;
|
|
160
|
+
if (result?.rule?.toolComponent?.index != null) {
|
|
161
|
+
tool = run.tool.extensions?.[result.rule.toolComponent.index];
|
|
162
|
+
}
|
|
163
|
+
if (!tool) {
|
|
164
|
+
tool = run.tool.driver;
|
|
165
|
+
}
|
|
166
|
+
return tool;
|
|
167
|
+
}
|
|
158
168
|
function findRuleByResult(run, result) {
|
|
159
169
|
const ruleData = {};
|
|
160
170
|
if (result.rule) {
|
|
161
|
-
if (result.rule?.index) {
|
|
171
|
+
if (result.rule?.index != null) {
|
|
162
172
|
ruleData.index = result.rule.index;
|
|
163
173
|
}
|
|
164
174
|
if (result.rule?.id) {
|
|
165
175
|
ruleData.id = result.rule.id;
|
|
166
176
|
}
|
|
167
177
|
}
|
|
168
|
-
if (
|
|
178
|
+
if (ruleData.index == null && result.ruleIndex != null) {
|
|
169
179
|
ruleData.index = result.ruleIndex;
|
|
170
180
|
}
|
|
171
|
-
if (ruleData.
|
|
172
|
-
|
|
181
|
+
if (!ruleData.id && result.ruleId) {
|
|
182
|
+
ruleData.id = result.ruleId;
|
|
183
|
+
}
|
|
184
|
+
const tool = findToolComponentByResult(run, result);
|
|
185
|
+
if (ruleData.index != null && tool?.rules && ruleData.index < tool.rules.length) {
|
|
186
|
+
return tool.rules[ruleData.index];
|
|
173
187
|
}
|
|
174
|
-
if (
|
|
175
|
-
return
|
|
176
|
-
(r) => r.id ===
|
|
188
|
+
if (ruleData.id && tool?.rules) {
|
|
189
|
+
return tool.rules.find(
|
|
190
|
+
(r) => r.id === ruleData.id
|
|
177
191
|
);
|
|
178
192
|
}
|
|
179
193
|
return void 0;
|
|
@@ -225,7 +239,7 @@ var SarifModelPerRun = class {
|
|
|
225
239
|
_securitySeverityMap;
|
|
226
240
|
_securityLevelMap;
|
|
227
241
|
constructor(run) {
|
|
228
|
-
this.toolName = run.
|
|
242
|
+
this.toolName = findToolComponentByResult(run, run.results?.[0]).name;
|
|
229
243
|
this._securitySeverityMap = (0, import_immutable.Map)().asMutable();
|
|
230
244
|
this._securityLevelMap = (0, import_immutable.Map)().asMutable();
|
|
231
245
|
this.buildSecuritySeverityMap(run);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { tryGetRulePropertyByResult } from '../utils/SarifUtils';
|
|
1
|
+
import { findToolComponentByResult, tryGetRulePropertyByResult } from '../utils/SarifUtils';
|
|
2
2
|
import { SecurityLevel, SecuritySeverity } from './types';
|
|
3
3
|
import Logger from '../Logger';
|
|
4
4
|
import { Map as ImmutableMap } from 'immutable';
|
|
@@ -14,7 +14,7 @@ export class SarifModelPerRun {
|
|
|
14
14
|
_securitySeverityMap;
|
|
15
15
|
_securityLevelMap;
|
|
16
16
|
constructor(run) {
|
|
17
|
-
this.toolName = run.
|
|
17
|
+
this.toolName = findToolComponentByResult(run, run.results?.[0]).name;
|
|
18
18
|
this._securitySeverityMap = ImmutableMap().asMutable();
|
|
19
19
|
this._securityLevelMap = ImmutableMap().asMutable();
|
|
20
20
|
this.buildSecuritySeverityMap(run);
|
|
@@ -87,4 +87,4 @@ export class SarifModelPerRun {
|
|
|
87
87
|
return sortSecurityLevelMap(this._securityLevelMap);
|
|
88
88
|
}
|
|
89
89
|
}
|
|
90
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
90
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiU2FyaWZNb2RlbFBlclJ1bi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9tb2RlbC9TYXJpZk1vZGVsUGVyUnVuLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUNBLE9BQU8sRUFDTCx5QkFBeUIsRUFDekIsMEJBQTBCLEVBQzNCLE1BQU0scUJBQXFCLENBQUE7QUFDNUIsT0FBTyxFQUFFLGFBQWEsRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLFNBQVMsQ0FBQTtBQUN6RCxPQUFPLE1BQU0sTUFBTSxXQUFXLENBQUE7QUFDOUIsT0FBTyxFQUFFLEdBQUcsSUFBSSxZQUFZLEVBQUUsTUFBTSxXQUFXLENBQUE7QUFDL0MsT0FBTyxFQUNMLG9CQUFvQixFQUNwQix1QkFBdUIsRUFDeEIsTUFBTSxvQkFBb0IsQ0FBQztBQUU1Qjs7Ozs7R0FLRztBQUNILE1BQU0sT0FBTyxnQkFBZ0I7SUFDWCxRQUFRLENBQVE7SUFFZixvQkFBb0IsQ0FBd0M7SUFDNUQsaUJBQWlCLENBQXFDO0lBRXZFLFlBQVksR0FBUTtRQUNsQixJQUFJLENBQUMsUUFBUSxHQUFHLHlCQUF5QixDQUFDLEdBQUcsRUFBRSxHQUFHLENBQUMsT0FBTyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUE7UUFFckUsSUFBSSxDQUFDLG9CQUFvQixHQUFHLFlBQVksRUFBNEIsQ0FBQyxTQUFTLEVBQUUsQ0FBQTtRQUNoRixJQUFJLENBQUMsaUJBQWlCLEdBQUcsWUFBWSxFQUF5QixDQUFDLFNBQVMsRUFBRSxDQUFBO1FBRTFFLElBQUksQ0FBQyx3QkFBd0IsQ0FBQyxHQUFHLENBQUMsQ0FBQTtRQUNsQyxJQUFJLENBQUMscUJBQXFCLENBQUMsR0FBRyxDQUFDLENBQUE7SUFDakMsQ0FBQztJQUVPLHdCQUF3QixDQUFDLEtBQWM7UUFDN0MsSUFBSSxLQUFLLEtBQUssU0FBUyxFQUFFLENBQUM7WUFDeEIsT0FBTyxnQkFBZ0IsQ0FBQyxPQUFPLENBQUE7UUFD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
|
package/dist/utils/SarifUtils.js
CHANGED
|
@@ -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 (
|
|
33
|
+
if (ruleData.index == null && result.ruleIndex != null) {
|
|
18
34
|
ruleData.index = result.ruleIndex;
|
|
19
35
|
}
|
|
20
|
-
if (ruleData.
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
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 (
|
|
27
|
-
return
|
|
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,
|
|
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.
|
|
10
|
+
export const LIB_VERSION = '0.2.4';
|
|
11
11
|
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidmVyc2lvbi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy92ZXJzaW9uLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7OztHQVFHO0FBQ0gsTUFBTSxDQUFDLE1BQU0sV0FBVyxHQUFHLE9BQU8sQ0FBQSJ9
|
package/jest.config.json
CHANGED
package/package.json
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
import type { Result, Run } from 'sarif';
|
|
2
|
-
import {
|
|
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.
|
|
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()
|
package/src/utils/SarifUtils.ts
CHANGED
|
@@ -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 (
|
|
40
|
+
if (ruleData.index == null && result.ruleIndex != null) {
|
|
22
41
|
ruleData.index = result.ruleIndex
|
|
23
42
|
}
|
|
24
43
|
|
|
25
|
-
if (ruleData.
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
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 (
|
|
33
|
-
return
|
|
34
|
-
(r: ReportingDescriptor): boolean => r.id ===
|
|
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
|
@@ -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
|
+
}
|