Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Parse Scan Ids even if URI-encoded #105

Merged
merged 8 commits into from
May 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .github/workflows/example.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,13 @@ jobs:
fail: false
pull: true

- name: Verify Scan Id
run: |
if [[ -z "${{ steps.scan.outputs.scan-id }}" ]]; then
echo "Scan step should've set a scan-id, it did not" >&2
exit 1
fi

- name: Verify scan result
run: |
result=${{ steps.scan.outputs.scan-result }}
Expand Down
30 changes: 13 additions & 17 deletions dist/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ var sr = __importStar(__nccwpck_require__(6889));
var inputs_1 = __nccwpck_require__(6180);
function run() {
return __awaiter(this, void 0, void 0, function () {
var _a, wizClientId, wizClientSecret, wizApiEndpointUrl, wizApiIdP, image, customPolicies, pull, fail_1, wizCredentials, wizcli, _b, scanId, scanPassed, result, summary, error_1, resultUrlBase, resultUrlHash, resultUrl, error_2;
var _a, wizClientId, wizClientSecret, wizApiEndpointUrl, wizApiIdP, image, customPolicies, pull, fail_1, wizCredentials, wizcli, _b, scanId, scanPassed, result, summary, error_1, error_2;
return __generator(this, function (_c) {
switch (_c.label) {
case 0:
Expand All @@ -157,7 +157,7 @@ function run() {
return [4, wizcli.scan(image, customPolicies)];
case 4:
_b = _c.sent(), scanId = _b.scanId, scanPassed = _b.scanPassed;
if (!wizApiEndpointUrl) return [3, 9];
if (!(scanId && wizApiEndpointUrl)) return [3, 9];
_c.label = 5;
case 5:
_c.trys.push([5, 8, , 9]);
Expand All @@ -182,16 +182,11 @@ function run() {
}
return [3, 9];
case 9:
resultUrlBase = "https://app.wiz.io/reports/cicd-scans";
resultUrlHash = fixedEncodeURIComponent("~(cicd_scan~'".concat(scanId, ")"));
resultUrl = "".concat(resultUrlBase, "#").concat(resultUrlHash);
if (scanPassed) {
core.info("Scan passed: ".concat(resultUrl));
core.setOutput("scan-id", scanId);
core.setOutput("scan-result", "success");
}
else {
core.warning("Scan failed: ".concat(resultUrl));
core.setOutput("scan-id", scanId);
core.setOutput("scan-result", "failed");
if (fail_1) {
Expand All @@ -216,11 +211,6 @@ function run() {
});
});
}
function fixedEncodeURIComponent(str) {
return encodeURIComponent(str).replace(/[!'()*]/g, function (c) {
return "%" + c.charCodeAt(0).toString(16);
});
}
run();


Expand Down Expand Up @@ -488,7 +478,8 @@ var __generator = (this && this.__generator) || function (thisArg, body) {
}
};
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.getWizCLI = void 0;
exports.parseScanId = exports.getWizCLI = void 0;
var core = __importStar(__nccwpck_require__(2186));
var exec = __importStar(__nccwpck_require__(1514));
var tc = __importStar(__nccwpck_require__(7784));
var WizCLI = (function () {
Expand Down Expand Up @@ -526,9 +517,8 @@ var WizCLI = (function () {
args = ["docker", "scan", "--image", image, "--no-style"].concat(policies ? ["--policy", policies] : []);
scanId = null;
listener = function (data) {
var match = data.toString().match(/cicd_scan~'([0-9a-f-]*)/);
if (match && match[1]) {
scanId = match[1];
if (!scanId) {
scanId = parseScanId(data.toString());
}
};
return [4, exec.exec(this.wizcli, args, {
Expand All @@ -544,7 +534,7 @@ var WizCLI = (function () {
throw new Error("wiz scan errored, status: ".concat(ec));
}
if (!scanId) {
throw new Error("Unable to parse Scan Id from report");
core.warning("Unable to parse Scan Id from report");
}
scanPassed = ec === 0;
return [2, {
Expand Down Expand Up @@ -576,6 +566,12 @@ function getWizCLI(credentials) {
});
}
exports.getWizCLI = getWizCLI;
var SCAN_ID_FORMAT = new RegExp("[0-9a-f]{8}-([0-9a-f]{4}-){3}[0-9a-f]{12}");
function parseScanId(str) {
var match = str.match(SCAN_ID_FORMAT);
return match ? match[0] : null;
}
exports.parseScanId = parseScanId;
function getWizInstallUrl() {
switch (process.platform) {
case "win32":
Expand Down
15 changes: 1 addition & 14 deletions src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ async function run() {
const wizcli = await wc.getWizCLI(wizCredentials);
const { scanId, scanPassed } = await wizcli.scan(image, customPolicies);

if (wizApiEndpointUrl) {
if (scanId && wizApiEndpointUrl) {
try {
const result = await sr.fetch(
scanId,
Expand All @@ -51,16 +51,10 @@ async function run() {
}
}

const resultUrlBase = "https://app.wiz.io/reports/cicd-scans";
const resultUrlHash = fixedEncodeURIComponent(`~(cicd_scan~'${scanId})`);
const resultUrl = `${resultUrlBase}#${resultUrlHash}`;

if (scanPassed) {
core.info(`Scan passed: ${resultUrl}`);
core.setOutput("scan-id", scanId);
core.setOutput("scan-result", "success");
} else {
core.warning(`Scan failed: ${resultUrl}`);
core.setOutput("scan-id", scanId);
core.setOutput("scan-result", "failed");

Expand All @@ -83,11 +77,4 @@ async function run() {
}
}

// https://stackoverflow.com/a/62436236
function fixedEncodeURIComponent(str: string): string {
return encodeURIComponent(str).replace(/[!'()*]/g, (c) => {
return "%" + c.charCodeAt(0).toString(16);
});
}

run();
19 changes: 19 additions & 0 deletions src/wiz-cli.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { parseScanId } from "./wiz-cli";

describe("parseScanId", () => {
it("parses un-encoded scan-id URLs", () => {
const scanId = parseScanId(
"https://app.wiz.io/findings/cicd-scans#~(cicd_scan~'8221aac6-eae9-4867-bbb6-91fbd1092f45)",
);

expect(scanId).toBe("8221aac6-eae9-4867-bbb6-91fbd1092f45");
});

it("parses encoded scan-id URLs", () => {
const scanId = parseScanId(
"https://app.wiz.io/findings/cicd-scans#%7E%28cicd_scan%7E%278221aac6-eae9-4867-bbb6-91fbd1092f45%29",
);

expect(scanId).toBe("8221aac6-eae9-4867-bbb6-91fbd1092f45");
});
});
19 changes: 14 additions & 5 deletions src/wiz-cli.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import * as core from "@actions/core";
import * as exec from "@actions/exec";
import * as tc from "@actions/tool-cache";
import type { WizCredentials } from "./wiz-config";

export type WizScanResult = {
scanId: string;
scanId: string | null;
scanPassed: boolean;
};

Expand Down Expand Up @@ -38,9 +39,8 @@ class WizCLI {
let scanId: string | null = null;

const listener = (data: Buffer) => {
const match = data.toString().match(/cicd_scan~'([0-9a-f-]*)/);
if (match && match[1]) {
scanId = match[1];
if (!scanId) {
scanId = parseScanId(data.toString());
}
};

Expand All @@ -57,7 +57,7 @@ class WizCLI {
}

if (!scanId) {
throw new Error("Unable to parse Scan Id from report");
core.warning("Unable to parse Scan Id from report");
}

const scanPassed = ec === 0;
Expand All @@ -76,6 +76,15 @@ export async function getWizCLI(credentials: WizCredentials): Promise<WizCLI> {
return new WizCLI(wizcli, credentials).auth();
}

// Example: "8221aac6-eae9-4867-bbb6-91fbd1092f45"
const SCAN_ID_FORMAT = new RegExp("[0-9a-f]{8}-([0-9a-f]{4}-){3}[0-9a-f]{12}");

// exported for testing
export function parseScanId(str: string): string | null {
const match = str.match(SCAN_ID_FORMAT);
return match ? match[0] : null;
}

function getWizInstallUrl(): string {
switch (process.platform) {
case "win32":
Expand Down
Loading