diff --git a/src/rules.ts b/src/rules.ts index adbd21d..ed40055 100644 --- a/src/rules.ts +++ b/src/rules.ts @@ -20,6 +20,14 @@ export const defaultRules: RedactionRule[] = [ pattern: /gh[pousr]_[A-Za-z0-9_]{20,}/g, replacement: indexed("GITHUB_TOKEN") }, + { + id: "slack-token", + type: "token", + severity: "secret", + description: "Slack bot/user/app token", + pattern: /xox[baprs]-[A-Za-z0-9-]{20,}/g, + replacement: indexed("SLACK_TOKEN") + }, { id: "aws-access-key", type: "aws_access_key", diff --git a/tests/scan.test.ts b/tests/scan.test.ts index e418d48..9a9890d 100644 --- a/tests/scan.test.ts +++ b/tests/scan.test.ts @@ -22,3 +22,11 @@ test("buildBundle summaries are deterministic", () => { assert.equal(bundle.summary.secrets, 1); assert.equal(bundle.summary.warnings, 2); }); + + +test("scanDocument redacts Slack-style chat tokens", () => { + const file = scanDocument({ path: "chat.log", content: "bot token xoxb-123456789012-ABCDEFGHIJKL-secretvalue\n" }); + assert.equal(file.findings.length, 1); + assert.match(file.sanitized, /\[REDACTED:SLACK_TOKEN_1\]/); + assert.doesNotMatch(file.sanitized, /xoxb-/); +});