From 0ce6420f8e7aab68e43369a36f1635e84e657c4c Mon Sep 17 00:00:00 2001 From: "Michael B. Gale" Date: Thu, 12 Feb 2026 20:15:18 +0000 Subject: [PATCH] Validate `CODEQL_ACTION_CSRA_ASSESSMENT_ID` value --- lib/analyze-action.js | 16 +++++++--- lib/init-action-post.js | 16 +++++++--- lib/upload-lib.js | 16 +++++++--- lib/upload-sarif-action.js | 16 +++++++--- src/analyses.test.ts | 61 ++++++++++++++++++++++++++++++++++++++ src/analyses.ts | 17 ++++++++--- src/environment.ts | 3 ++ 7 files changed, 125 insertions(+), 20 deletions(-) diff --git a/lib/analyze-action.js b/lib/analyze-action.js index a22217bb2..e7e5a5f08 100644 --- a/lib/analyze-action.js +++ b/lib/analyze-action.js @@ -106511,10 +106511,18 @@ var CodeQuality = { transformPayload: (payload) => payload }; function addAssessmentId(payload) { - const assessmentId = parseInt( - getRequiredEnvParam("CODEQL_ACTION_CSRA_ASSESSMENT_ID"), - 10 - ); + const rawAssessmentId = getRequiredEnvParam("CODEQL_ACTION_CSRA_ASSESSMENT_ID" /* CSRA_ASSESSMENT_ID */); + const assessmentId = parseInt(rawAssessmentId, 10); + if (Number.isNaN(assessmentId)) { + throw new Error( + `${"CODEQL_ACTION_CSRA_ASSESSMENT_ID" /* CSRA_ASSESSMENT_ID */} must not be NaN: ${rawAssessmentId}` + ); + } + if (assessmentId < 0) { + throw new Error( + `${"CODEQL_ACTION_CSRA_ASSESSMENT_ID" /* CSRA_ASSESSMENT_ID */} must not be negative: ${rawAssessmentId}` + ); + } return { sarif: payload.sarif, assessment_id: assessmentId }; } var CSRA = { diff --git a/lib/init-action-post.js b/lib/init-action-post.js index e19a9678c..12a8686cd 100644 --- a/lib/init-action-post.js +++ b/lib/init-action-post.js @@ -164570,10 +164570,18 @@ var CodeQuality = { transformPayload: (payload) => payload }; function addAssessmentId(payload) { - const assessmentId = parseInt( - getRequiredEnvParam("CODEQL_ACTION_CSRA_ASSESSMENT_ID"), - 10 - ); + const rawAssessmentId = getRequiredEnvParam("CODEQL_ACTION_CSRA_ASSESSMENT_ID" /* CSRA_ASSESSMENT_ID */); + const assessmentId = parseInt(rawAssessmentId, 10); + if (Number.isNaN(assessmentId)) { + throw new Error( + `${"CODEQL_ACTION_CSRA_ASSESSMENT_ID" /* CSRA_ASSESSMENT_ID */} must not be NaN: ${rawAssessmentId}` + ); + } + if (assessmentId < 0) { + throw new Error( + `${"CODEQL_ACTION_CSRA_ASSESSMENT_ID" /* CSRA_ASSESSMENT_ID */} must not be negative: ${rawAssessmentId}` + ); + } return { sarif: payload.sarif, assessment_id: assessmentId }; } var CSRA = { diff --git a/lib/upload-lib.js b/lib/upload-lib.js index 53c52c219..9a1704672 100644 --- a/lib/upload-lib.js +++ b/lib/upload-lib.js @@ -106166,10 +106166,18 @@ var CodeQuality = { transformPayload: (payload) => payload }; function addAssessmentId(payload) { - const assessmentId = parseInt( - getRequiredEnvParam("CODEQL_ACTION_CSRA_ASSESSMENT_ID"), - 10 - ); + const rawAssessmentId = getRequiredEnvParam("CODEQL_ACTION_CSRA_ASSESSMENT_ID" /* CSRA_ASSESSMENT_ID */); + const assessmentId = parseInt(rawAssessmentId, 10); + if (Number.isNaN(assessmentId)) { + throw new Error( + `${"CODEQL_ACTION_CSRA_ASSESSMENT_ID" /* CSRA_ASSESSMENT_ID */} must not be NaN: ${rawAssessmentId}` + ); + } + if (assessmentId < 0) { + throw new Error( + `${"CODEQL_ACTION_CSRA_ASSESSMENT_ID" /* CSRA_ASSESSMENT_ID */} must not be negative: ${rawAssessmentId}` + ); + } return { sarif: payload.sarif, assessment_id: assessmentId }; } var CSRA = { diff --git a/lib/upload-sarif-action.js b/lib/upload-sarif-action.js index c8994877d..a68eb7fd3 100644 --- a/lib/upload-sarif-action.js +++ b/lib/upload-sarif-action.js @@ -106204,10 +106204,18 @@ var CodeQuality = { transformPayload: (payload) => payload }; function addAssessmentId(payload) { - const assessmentId = parseInt( - getRequiredEnvParam("CODEQL_ACTION_CSRA_ASSESSMENT_ID"), - 10 - ); + const rawAssessmentId = getRequiredEnvParam("CODEQL_ACTION_CSRA_ASSESSMENT_ID" /* CSRA_ASSESSMENT_ID */); + const assessmentId = parseInt(rawAssessmentId, 10); + if (Number.isNaN(assessmentId)) { + throw new Error( + `${"CODEQL_ACTION_CSRA_ASSESSMENT_ID" /* CSRA_ASSESSMENT_ID */} must not be NaN: ${rawAssessmentId}` + ); + } + if (assessmentId < 0) { + throw new Error( + `${"CODEQL_ACTION_CSRA_ASSESSMENT_ID" /* CSRA_ASSESSMENT_ID */} must not be negative: ${rawAssessmentId}` + ); + } return { sarif: payload.sarif, assessment_id: assessmentId }; } var CSRA = { diff --git a/src/analyses.test.ts b/src/analyses.test.ts index b4a24f4ff..89fe7b4fd 100644 --- a/src/analyses.test.ts +++ b/src/analyses.test.ts @@ -8,13 +8,16 @@ import { AnalysisKind, CodeScanning, compatibilityMatrix, + CSRA, getAnalysisConfig, getAnalysisKinds, parseAnalysisKinds, supportedAnalysisKinds, } from "./analyses"; +import { EnvVar } from "./environment"; import { getRunnerLogger } from "./logging"; import { setupTests } from "./testing-utils"; +import { AssessmentPayload } from "./upload-lib/types"; import { ConfigurationError } from "./util"; setupTests(test); @@ -118,3 +121,61 @@ test("Code Scanning configuration does not accept other SARIF extensions", (t) = t.false(CodeScanning.sarifPredicate(sarifPath)); } }); + +test("CSRA configuration transforms SARIF upload payload", (t) => { + process.env[EnvVar.CSRA_ASSESSMENT_ID] = "1"; + const payload = CSRA.transformPayload({ + commit_oid: "abc", + sarif: "sarif", + ref: "ref", + workflow_run_attempt: 1, + workflow_run_id: 1, + checkout_uri: "uri", + tool_names: [], + }) as AssessmentPayload; + + const expected: AssessmentPayload = { sarif: "sarif", assessment_id: 1 }; + t.deepEqual(expected, payload); +}); + +test("CSRA configuration throws for negative assessment IDs", (t) => { + process.env[EnvVar.CSRA_ASSESSMENT_ID] = "-1"; + t.throws( + () => + CSRA.transformPayload({ + commit_oid: "abc", + sarif: "sarif", + ref: "ref", + workflow_run_attempt: 1, + workflow_run_id: 1, + checkout_uri: "uri", + tool_names: [], + }), + { + instanceOf: Error, + message: (msg) => + msg.startsWith(`${EnvVar.CSRA_ASSESSMENT_ID} must not be negative: `), + }, + ); +}); + +test("CSRA configuration throws for invalid IDs", (t) => { + process.env[EnvVar.CSRA_ASSESSMENT_ID] = "foo"; + t.throws( + () => + CSRA.transformPayload({ + commit_oid: "abc", + sarif: "sarif", + ref: "ref", + workflow_run_attempt: 1, + workflow_run_id: 1, + checkout_uri: "uri", + tool_names: [], + }), + { + instanceOf: Error, + message: (msg) => + msg.startsWith(`${EnvVar.CSRA_ASSESSMENT_ID} must not be NaN: `), + }, + ); +}); diff --git a/src/analyses.ts b/src/analyses.ts index ce7f10158..ecc62fd15 100644 --- a/src/analyses.ts +++ b/src/analyses.ts @@ -3,6 +3,7 @@ import { getOptionalInput, getRequiredInput, } from "./actions-util"; +import { EnvVar } from "./environment"; import { Logger } from "./logging"; import { AssessmentPayload, @@ -187,10 +188,18 @@ export const CodeQuality: AnalysisConfig = { * @param payload The base payload. */ function addAssessmentId(payload: UploadPayload): AssessmentPayload { - const assessmentId = parseInt( - getRequiredEnvParam("CODEQL_ACTION_CSRA_ASSESSMENT_ID"), - 10, - ); + const rawAssessmentId = getRequiredEnvParam(EnvVar.CSRA_ASSESSMENT_ID); + const assessmentId = parseInt(rawAssessmentId, 10); + if (Number.isNaN(assessmentId)) { + throw new Error( + `${EnvVar.CSRA_ASSESSMENT_ID} must not be NaN: ${rawAssessmentId}`, + ); + } + if (assessmentId < 0) { + throw new Error( + `${EnvVar.CSRA_ASSESSMENT_ID} must not be negative: ${rawAssessmentId}`, + ); + } return { sarif: payload.sarif, assessment_id: assessmentId }; } diff --git a/src/environment.ts b/src/environment.ts index 4d7b44c80..3a71a8f2a 100644 --- a/src/environment.ts +++ b/src/environment.ts @@ -141,4 +141,7 @@ export enum EnvVar { * `getAnalysisKey`, but can also be set manually for testing and non-standard applications. */ ANALYSIS_KEY = "CODEQL_ACTION_ANALYSIS_KEY", + + /** Used by CSRA to communicate the assessment ID to the CodeQL Action. */ + CSRA_ASSESSMENT_ID = "CODEQL_ACTION_CSRA_ASSESSMENT_ID", }