diff --git a/.github/workflows/opengrep-precise-full.yml b/.github/workflows/opengrep-precise-full.yml index d4659753c3af..b4da576a9df5 100644 --- a/.github/workflows/opengrep-precise-full.yml +++ b/.github/workflows/opengrep-precise-full.yml @@ -38,9 +38,13 @@ jobs: OPENGREP_VERSION: v1.22.0 OPENGREP_INSTALL_SHA: f458d7f0d52cc58eae1ca3cf3d5caf101e637519 run: | - curl -fsSL --connect-timeout 30 --max-time 120 \ - "https://raw.githubusercontent.com/opengrep/opengrep/${OPENGREP_INSTALL_SHA}/install.sh" \ - | bash -s -- -v "$OPENGREP_VERSION" + # Download first so a timed-out transfer cannot execute a partial installer. + installer="$(mktemp "${RUNNER_TEMP}/opengrep-install.XXXXXX")" + trap 'rm -f "$installer"' EXIT + curl -fsSL --connect-timeout 10 --max-time 120 \ + -o "$installer" \ + "https://raw.githubusercontent.com/opengrep/opengrep/${OPENGREP_INSTALL_SHA}/install.sh" + bash "$installer" -v "$OPENGREP_VERSION" echo "$HOME/.opengrep/cli/latest" >> "$GITHUB_PATH" - name: Verify opengrep diff --git a/.github/workflows/opengrep-precise.yml b/.github/workflows/opengrep-precise.yml index 2e9446f902dd..ed83d60063ec 100644 --- a/.github/workflows/opengrep-precise.yml +++ b/.github/workflows/opengrep-precise.yml @@ -64,9 +64,13 @@ jobs: OPENGREP_VERSION: v1.22.0 OPENGREP_INSTALL_SHA: f458d7f0d52cc58eae1ca3cf3d5caf101e637519 run: | - curl -fsSL --connect-timeout 30 --max-time 120 \ - "https://raw.githubusercontent.com/opengrep/opengrep/${OPENGREP_INSTALL_SHA}/install.sh" \ - | bash -s -- -v "$OPENGREP_VERSION" + # Download first so a timed-out transfer cannot execute a partial installer. + installer="$(mktemp "${RUNNER_TEMP}/opengrep-install.XXXXXX")" + trap 'rm -f "$installer"' EXIT + curl -fsSL --connect-timeout 10 --max-time 120 \ + -o "$installer" \ + "https://raw.githubusercontent.com/opengrep/opengrep/${OPENGREP_INSTALL_SHA}/install.sh" + bash "$installer" -v "$OPENGREP_VERSION" echo "$HOME/.opengrep/cli/latest" >> "$GITHUB_PATH" - name: Verify opengrep diff --git a/test/scripts/ci-workflow-guards.test.ts b/test/scripts/ci-workflow-guards.test.ts index 3def3b261fe5..2d30d53ef802 100644 --- a/test/scripts/ci-workflow-guards.test.ts +++ b/test/scripts/ci-workflow-guards.test.ts @@ -1670,6 +1670,29 @@ describe("ci workflow guards", () => { } }); + it("downloads the opengrep installer completely before execution", () => { + for (const workflowPath of [OPENGREP_PR_DIFF_WORKFLOW, OPENGREP_FULL_WORKFLOW]) { + const workflow = parse(readFileSync(workflowPath, "utf8")); + const run = expectDefined( + workflow.jobs.scan.steps.find((step: WorkflowStep) => step.name === "Install opengrep") + ?.run, + `Install opengrep step in ${workflowPath}`, + ); + + expect(run, workflowPath).toContain( + 'installer="$(mktemp "${RUNNER_TEMP}/opengrep-install.XXXXXX")"', + ); + expect(run, workflowPath).toContain("curl -fsSL --connect-timeout 10 --max-time 120 \\"); + expect(run, workflowPath).toContain('-o "$installer"'); + expect(run, workflowPath).toContain('bash "$installer" -v "$OPENGREP_VERSION"'); + expect(run, workflowPath).toContain("trap 'rm -f \"$installer\"' EXIT"); + expect(run.indexOf('-o "$installer"'), workflowPath).toBeLessThan( + run.indexOf('bash "$installer"'), + ); + expect(run, workflowPath).not.toMatch(/\|\s*bash/u); + } + }); + it("runs real behavior proof from the trusted workflow revision", () => { const workflow = readRealBehaviorProofWorkflow(); const source = readFileSync(".github/workflows/real-behavior-proof.yml", "utf8"); @@ -4279,11 +4302,4 @@ printf '%s\n' "\${CURL_SUCCESS_IP:-203.0.113.7}" 'call.getFile().getRelativePath() = "extensions/codex/src/app-server/transport-websocket.ts"', ); }); - - it("bounds Opengrep installer downloads with connect timeout", () => { - for (const path of [OPENGREP_PR_DIFF_WORKFLOW, OPENGREP_FULL_WORKFLOW]) { - const workflow = readFileSync(path, "utf8"); - expect(workflow).toContain("curl -fsSL --connect-timeout 30 --max-time 120"); - } - }); });