diff --git a/CHANGELOG.md b/CHANGELOG.md
index 420ab04..550e4ee 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -7,6 +7,20 @@ This project follows [Keep a Changelog](https://keepachangelog.com/) and [Semant
### Added
+-
+
+### Changed
+
+-
+
+### Fixed
+
+-
+
+## [2.3.12] - 2025-12-18
+
+### Added
+
- Added warnings count to scan usage stats.
### Changed
@@ -19,7 +33,7 @@ This project follows [Keep a Changelog](https://keepachangelog.com/) and [Semant
### Fixed
--
+- Fixed false positive secret detection for certain harmless attribute keys in codebase scanner.
## [2.3.11] - 2025-12-13
diff --git a/src/core/secretDetectors.ts b/src/core/secretDetectors.ts
index 1814b1a..6e42a85 100644
--- a/src/core/secretDetectors.ts
+++ b/src/core/secretDetectors.ts
@@ -44,6 +44,10 @@ const HARMLESS_URLS = [
/xmlns=["']http:\/\/www\.w3\.org\/2000\/svg["']/i, // SVG namespace
];
+// Known harmless attribute keys commonly used in UI / analytics
+const HARMLESS_ATTRIBUTE_KEYS =
+ /\b(trackingId|trackingContext|data-testid|data-test|aria-label)\b/i;
+
/**
* Determines the severity of a secret finding.
* @param kind 'pattern' | 'entropy'
@@ -256,7 +260,10 @@ export function detectSecretsInSource(
// 1) Suspicious key literal assignments
if (SUSPICIOUS_KEYS.test(line)) {
- const m = line!.match(/=\s*["'`](.+?)["'`]/);
+ // Ignore known harmless UI / analytics attributes
+ if (HARMLESS_ATTRIBUTE_KEYS.test(line)) continue;
+
+ const m = line.match(/=\s*["'`](.+?)["'`]/);
if (
m &&
m[1] &&
diff --git a/src/ui/scan/printStats.ts b/src/ui/scan/printStats.ts
index 4521e5b..14f3dd6 100644
--- a/src/ui/scan/printStats.ts
+++ b/src/ui/scan/printStats.ts
@@ -27,9 +27,7 @@ export function printStats(
console.log(
chalk.magenta.dim(` Unique variables: ${stats.uniqueVariables}`),
);
- console.log(
- chalk.magenta.dim(` Warnings: ${stats.warningsCount}`),
- );
+ console.log(chalk.magenta.dim(` Warnings: ${stats.warningsCount}`));
console.log(
chalk.magenta.dim(` Scan duration: ${stats.duration.toFixed(2)}s`),
);
diff --git a/test/e2e/cli.secrets.e2e.test.ts b/test/e2e/cli.secrets.e2e.test.ts
index 5d5ae51..a8ed0e1 100644
--- a/test/e2e/cli.secrets.e2e.test.ts
+++ b/test/e2e/cli.secrets.e2e.test.ts
@@ -270,4 +270,32 @@ describe('secrets detection (default scan mode)', () => {
expect(res.status).toBe(0);
expect(res.stdout).not.toContain('Potential secrets detected in codebase:');
});
+ it('does not warn on UI tracking attributes containing auth keywords', () => {
+ const cwd = tmpDir();
+
+ fs.writeFileSync(path.join(cwd, '.env'), 'DUMMY=\n');
+ fs.mkdirSync(path.join(cwd, 'src'), { recursive: true });
+
+ fs.writeFileSync(
+ path.join(cwd, 'src', 'page.svelte'),
+ `
+
+
+
+ `.trimStart(),
+ );
+
+ const res = runCli(cwd, []);
+
+ expect(res.status).toBe(0);
+ expect(res.stdout).not.toContain('Potential secrets detected in codebase:');
+ });
});