From 615a7130b5e3a392c3d0be096d095ba365253205 Mon Sep 17 00:00:00 2001 From: Hirsch Singhal Date: Mon, 25 May 2026 09:38:54 -0700 Subject: [PATCH 1/3] Fix ghs_ token patterns to support new token format Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- lib/entry-points.js | 22 +++++++++++++++------- src/artifact-scanner.test.ts | 21 +++++++++++++++------ src/artifact-scanner.ts | 25 ++++++++++++++++++------- 3 files changed, 48 insertions(+), 20 deletions(-) diff --git a/lib/entry-points.js b/lib/entry-points.js index 78a5f058af..53cf6ec342 100644 --- a/lib/entry-points.js +++ b/lib/entry-points.js @@ -158049,7 +158049,7 @@ var GITHUB_TOKEN_PATTERNS = [ }, { type: "Server-to-Server Token" /* ServerToServer */, - pattern: /\bghs_[a-zA-Z0-9]{36}\b/g + pattern: /ghs_[A-Za-z0-9._]{36,}/g }, { type: "Refresh Token" /* Refresh */, @@ -158057,7 +158057,7 @@ var GITHUB_TOKEN_PATTERNS = [ }, { type: "App Installation Access Token" /* AppInstallationAccess */, - pattern: /\bghs_[a-zA-Z0-9]{255}\b/g + pattern: /ghs_[A-Za-z0-9._]{36,}/g } ]; function isAuthToken(value, patterns = GITHUB_TOKEN_PATTERNS) { @@ -158070,15 +158070,23 @@ function isAuthToken(value, patterns = GITHUB_TOKEN_PATTERNS) { } function scanFileForTokens(filePath, relativePath, logger) { const findings = []; + const seenMatches = /* @__PURE__ */ new Set(); try { const content = fs23.readFileSync(filePath, "utf8"); for (const { type: type2, pattern } of GITHUB_TOKEN_PATTERNS) { - const matches = content.match(pattern); - if (matches) { - for (let i = 0; i < matches.length; i++) { - findings.push({ tokenType: type2, filePath: relativePath }); + const regex = new RegExp(pattern.source, pattern.flags); + let matchCount = 0; + for (const match of content.matchAll(regex)) { + const index = match.index; + if (index === void 0 || seenMatches.has(index)) { + continue; } - logger.debug(`Found ${matches.length} ${type2}(s) in ${relativePath}`); + seenMatches.add(index); + findings.push({ tokenType: type2, filePath: relativePath }); + matchCount++; + } + if (matchCount > 0) { + logger.debug(`Found ${matchCount} ${type2}(s) in ${relativePath}`); } } return findings; diff --git a/src/artifact-scanner.test.ts b/src/artifact-scanner.test.ts index 56f99e1138..a0a41f2c56 100644 --- a/src/artifact-scanner.test.ts +++ b/src/artifact-scanner.test.ts @@ -23,6 +23,9 @@ test("makeTestToken", (t) => { t.is(makeTestToken(255).length, 255); }); +const NEW_FORMAT_GHS_TOKEN = + "ghs_abc123.def456.ghi789_abc123.def456.ghi789"; + test("isAuthToken", (t) => { // Undefined for strings that aren't tokens t.is(isAuthToken("some string"), undefined); @@ -32,9 +35,10 @@ test("isAuthToken", (t) => { // Token types for strings that are tokens. t.is(isAuthToken(`ghp_${makeTestToken()}`), TokenType.PersonalAccessClassic); t.is(isAuthToken(`ghp_${makeTestToken()}`), TokenType.PersonalAccessClassic); + t.is(isAuthToken(NEW_FORMAT_GHS_TOKEN), TokenType.ServerToServer); t.is( isAuthToken(`ghs_${makeTestToken(255)}`), - TokenType.AppInstallationAccess, + TokenType.ServerToServer, ); t.is( isAuthToken(`github_pat_${makeTestToken(22)}_${makeTestToken(59)}`), @@ -52,6 +56,15 @@ test("isAuthToken", (t) => { ]), undefined, ); + t.is( + isAuthToken(NEW_FORMAT_GHS_TOKEN, [ + { + type: TokenType.AppInstallationAccess, + pattern: /ghs_[A-Za-z0-9._]{36,}/g, + }, + ]), + TokenType.AppInstallationAccess, + ); }); const testTokens = [ @@ -76,16 +89,12 @@ const testTokens = [ }, { type: TokenType.ServerToServer, - value: `ghs_${makeTestToken()}`, + value: NEW_FORMAT_GHS_TOKEN, }, { type: TokenType.Refresh, value: `ghr_${makeTestToken()}`, }, - { - type: TokenType.AppInstallationAccess, - value: `ghs_${makeTestToken(255)}`, - }, ]; for (const { type, value, checkPattern } of testTokens) { diff --git a/src/artifact-scanner.ts b/src/artifact-scanner.ts index 5f238811a1..ae53859816 100644 --- a/src/artifact-scanner.ts +++ b/src/artifact-scanner.ts @@ -55,7 +55,7 @@ const GITHUB_TOKEN_PATTERNS: TokenPattern[] = [ }, { type: TokenType.ServerToServer, - pattern: /\bghs_[a-zA-Z0-9]{36}\b/g, + pattern: /ghs_[A-Za-z0-9._]{36,}/g, }, { type: TokenType.Refresh, @@ -63,7 +63,7 @@ const GITHUB_TOKEN_PATTERNS: TokenPattern[] = [ }, { type: TokenType.AppInstallationAccess, - pattern: /\bghs_[a-zA-Z0-9]{255}\b/g, + pattern: /ghs_[A-Za-z0-9._]{36,}/g, }, ]; @@ -109,16 +109,27 @@ function scanFileForTokens( logger: Logger, ): TokenFinding[] { const findings: TokenFinding[] = []; + const seenMatches = new Set(); try { const content = fs.readFileSync(filePath, "utf8"); for (const { type, pattern } of GITHUB_TOKEN_PATTERNS) { - const matches = content.match(pattern); - if (matches) { - for (let i = 0; i < matches.length; i++) { - findings.push({ tokenType: type, filePath: relativePath }); + const regex = new RegExp(pattern.source, pattern.flags); + let matchCount = 0; + + for (const match of content.matchAll(regex)) { + const index = match.index; + if (index === undefined || seenMatches.has(index)) { + continue; } - logger.debug(`Found ${matches.length} ${type}(s) in ${relativePath}`); + + seenMatches.add(index); + findings.push({ tokenType: type, filePath: relativePath }); + matchCount++; + } + + if (matchCount > 0) { + logger.debug(`Found ${matchCount} ${type}(s) in ${relativePath}`); } } From df3ab55560b70a5b28de940a31f4fd76dd68ffd9 Mon Sep 17 00:00:00 2001 From: Hirsch Singhal <1666363+hpsin@users.noreply.github.com> Date: Tue, 26 May 2026 09:32:01 -0700 Subject: [PATCH 2/3] Fix ghs_ regex: add dash to character class [A-Za-z0-9._-] --- src/artifact-scanner.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/artifact-scanner.ts b/src/artifact-scanner.ts index ae53859816..95d7f99181 100644 --- a/src/artifact-scanner.ts +++ b/src/artifact-scanner.ts @@ -55,7 +55,7 @@ const GITHUB_TOKEN_PATTERNS: TokenPattern[] = [ }, { type: TokenType.ServerToServer, - pattern: /ghs_[A-Za-z0-9._]{36,}/g, + pattern: /ghs_[A-Za-z0-9._-]{36,}/g, }, { type: TokenType.Refresh, @@ -63,7 +63,7 @@ const GITHUB_TOKEN_PATTERNS: TokenPattern[] = [ }, { type: TokenType.AppInstallationAccess, - pattern: /ghs_[A-Za-z0-9._]{36,}/g, + pattern: /ghs_[A-Za-z0-9._-]{36,}/g, }, ]; From b53799fa81226bc949086c285acc6091b7286ba7 Mon Sep 17 00:00:00 2001 From: Hirsch Singhal <1666363+hpsin@users.noreply.github.com> Date: Tue, 26 May 2026 09:32:02 -0700 Subject: [PATCH 3/3] Fix ghs_ regex: add dash to character class [A-Za-z0-9._-] --- src/artifact-scanner.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/artifact-scanner.test.ts b/src/artifact-scanner.test.ts index a0a41f2c56..3fb2d34fea 100644 --- a/src/artifact-scanner.test.ts +++ b/src/artifact-scanner.test.ts @@ -60,7 +60,7 @@ test("isAuthToken", (t) => { isAuthToken(NEW_FORMAT_GHS_TOKEN, [ { type: TokenType.AppInstallationAccess, - pattern: /ghs_[A-Za-z0-9._]{36,}/g, + pattern: /ghs_[A-Za-z0-9._-]{36,}/g, }, ]), TokenType.AppInstallationAccess,