Skip to content

Commit a35fbdf

Browse files
committed
ignore html secrets
1 parent a03cf30 commit a35fbdf

4 files changed

Lines changed: 90 additions & 7 deletions

File tree

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@ This project follows [Keep a Changelog](https://keepachangelog.com/) and [Semant
1616
### Fixed
1717
- Fixed issue where .env.example would be ignored by git when using --fix flag.
1818

19+
### Added
20+
- HTML comments to ignore secret detection in HTML lines (e.g. `<!-- dotenv-diff-ignore -->`).
21+
1922
## [2.2.8] - 2025-09-30
2023
### Added
2124
- Fix .env is not ignored by git when using --fix flag.

src/commands/scanUsage.ts

Lines changed: 34 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import { createJsonOutput } from '../core/scanJsonOutput.js';
1010
import { printMissingExample } from '../ui/scan/printMissingExample.js';
1111
import { processComparisonFile } from '../core/processComparisonFile.js';
1212
import { printComparisonError } from '../ui/scan/printComparisonError.js';
13+
import { hasIgnoreComment } from '../core/secretDetectors.js';
1314

1415
/**
1516
* Filters out commented usages from the list.
@@ -18,15 +19,45 @@ import { printComparisonError } from '../ui/scan/printComparisonError.js';
1819
* # process.env.API_URL
1920
* /* process.env.API_URL
2021
* * process.env.API_URL
22+
* <!-- process.env.API_URL -->
2123
* @param usages - List of environment variable usages
2224
* @returns Filtered list of environment variable usages
2325
*/
2426
function skipCommentedUsages(usages: EnvUsage[]): EnvUsage[] {
25-
return usages.filter(
26-
(u) => u.context && !/^\s*(\/\/|#|\/\*|\*)/.test(u.context.trim()),
27-
);
27+
let insideHtmlComment = false;
28+
let insideIgnoreBlock = false;
29+
30+
return usages.filter((u) => {
31+
if (!u.context) return true;
32+
const line = u.context.trim();
33+
34+
if (line.includes('<!--')) insideHtmlComment = true;
35+
if (line.includes('-->')) {
36+
insideHtmlComment = false;
37+
return false;
38+
}
39+
40+
if (/<!--\s*dotenv[\s-]*diff[\s-]*ignore[\s-]*start\s*-->/i.test(line)) {
41+
insideIgnoreBlock = true;
42+
return false;
43+
}
44+
45+
if (/<!--\s*dotenv[\s-]*diff[\s-]*ignore[\s-]*end\s*-->/i.test(line)) {
46+
insideIgnoreBlock = false;
47+
return false;
48+
}
49+
50+
if (insideIgnoreBlock) return false;
51+
52+
return (
53+
!insideHtmlComment &&
54+
!/^\s*(\/\/|#|\/\*|\*|<!--|-->)/.test(line) &&
55+
!hasIgnoreComment(line)
56+
);
57+
});
2858
}
2959

60+
3061
/**
3162
* Recalculates statistics for a scan result after filtering usages.
3263
* @param scanResult The current scan result

src/core/secretDetectors.ts

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -43,14 +43,19 @@ const HARMLESS_URLS = [
4343

4444
/**
4545
* Checks if a line has an ignore comment
46-
* fx: // dotenv-diff-ignore or /* dotenv-diff-ignore
46+
* fx: // dotenv-diff-ignore or /* dotenv-diff-ignore *\/ or <!-- dotenv-diff-ignore -->
4747
* @param line - The line to check
4848
* @returns True if the line should be ignored
4949
*/
50-
function hasIgnoreComment(line: string): boolean {
50+
export function hasIgnoreComment(line: string): boolean {
51+
const normalized = line.trim();
52+
53+
// Allow mixed casing, extra spaces, and optional dashes
5154
return (
52-
/\/\/\s*dotenv-diff-ignore/.test(line) ||
53-
/\/\*\s*dotenv-diff-ignore\s*\*\//.test(line)
55+
/\/\/.*dotenv[\s-]*diff[\s-]*ignore/i.test(normalized) ||
56+
/\/\*.*dotenv[\s-]*diff[\s-]*ignore.*\*\//i.test(normalized) ||
57+
/<!--.*dotenv[\s-]*diff[\s-]*ignore.*-->/i.test(normalized) ||
58+
/\bdotenv[\s-]*diff[\s-]*ignore\b/i.test(normalized)
5459
);
5560
}
5661

@@ -139,10 +144,25 @@ export function detectSecretsInSource(
139144
const findings: SecretFinding[] = [];
140145
const lines = source.split(/\r?\n/);
141146

147+
let insideIgnoreBlock = false;
148+
142149
for (let i = 0; i < lines.length; i++) {
143150
const lineNo = i + 1;
144151
const line = lines[i] || '';
145152

153+
if (/<!--\s*dotenv[\s-]*diff[\s-]*ignore[\s-]*start\s*-->/i.test(line)) {
154+
insideIgnoreBlock = true;
155+
continue;
156+
}
157+
158+
if (/<!--\s*dotenv[\s-]*diff[\s-]*ignore[\s-]*end\s*-->/i.test(line)) {
159+
insideIgnoreBlock = false;
160+
continue;
161+
}
162+
163+
// Skip if inside ignore block
164+
if (insideIgnoreBlock) continue;
165+
146166
// Skip comments
147167
if (/^\s*\/\//.test(line)) continue;
148168

test/e2e/cli.autoscan.e2e.test.ts

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,4 +103,33 @@ describe('no-flag autoscan', () => {
103103
const gitignore = fs.readFileSync(path.join(cwd, '.gitignore'), 'utf-8');
104104
expect(gitignore).toContain('.env');
105105
});
106+
it('will ignore <!-- dotenv-diff-ignore --> and block comments in .env files', () => {
107+
const cwd = tmpDir();
108+
109+
fs.mkdirSync(path.join(cwd, 'src'), { recursive: true });
110+
111+
// Skriv +page.svelte med både inline og blok-ignore
112+
fs.writeFileSync(
113+
path.join(cwd, 'src', '+page.svelte'),
114+
`
115+
// Inline ignore test
116+
const apiKey = process.env.API_KEY; <!-- dotEnv- difF- igNore -->
117+
const secret = process.env.SECRET; // should be detected
118+
119+
// Block ignore test
120+
<!-- dotenv-diff-ignore-start -->
121+
<p>Environment: "https://thisissecrethttpslasdasdasdasdasd.com"</p>
122+
<!-- dotenv-diff-ignore-end -->
123+
124+
<p>Environment: "https://thisissecrethttpslasdasdasdasdasd.com"</p> <!-- dotenv-diff-ignore -->
125+
126+
const visible = process.env.VISIBLE; // should be detected
127+
`.trim(),
128+
);
129+
130+
const res = runCli(cwd, []);
131+
132+
expect(res.status).toBe(0);
133+
expect(res.stdout).not.toContain('Potential secrets detected in codebase:');
134+
});
106135
});

0 commit comments

Comments
 (0)