Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/fair-places-care.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'dotenv-diff': patch
---

ignore minified lines for env usage
2 changes: 2 additions & 0 deletions docs/capabilities.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ Default scanned file types: .ts, .js, jsx, tsx, vue, .mjs, .mts, .cjs, .cts, .sv

## What It Checks For

> **Note:** The scanner skips files containing any line over 500 characters, as these are likely minified or bundled — this avoids false positives across all checks below.

### 1 Missing Variables

Variables that are **used in code** but **not defined** in the selected env comparison file.
Expand Down
7 changes: 7 additions & 0 deletions packages/cli/src/core/helpers/isLikelyMinified.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
/**
* Returns true if a line looks like minified/bundled code.
* Used to skip entire files early in the pipeline.
*/
export function isLikelyMinified(content: string): boolean {
return content.split(/\r?\n/).some((line) => line.length > 500);
}
4 changes: 4 additions & 0 deletions packages/cli/src/core/scan/scanFile.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import type { EnvUsage, ScanOptions } from '../../config/types.js';
import { ENV_PATTERNS } from './patterns.js';
import { hasIgnoreComment } from '../security/secretDetectors.js';
import { normalizePath } from '../helpers/normalizePath.js';
import { isLikelyMinified } from '../helpers/isLikelyMinified.js';

/**
* Scans a file for environment variable usage.
Expand Down Expand Up @@ -62,6 +63,9 @@ export function scanFile(
// Get the context (the actual line)
const contextLine = lines[lineNumber - 1]!;

// Ignore likely minified / bundled lines to avoid scan false positives
if (isLikelyMinified(contextLine)) continue;

// Determine previous line for ignore detection
const prevLine = lines[lineNumber - 2] ?? '';

Expand Down
6 changes: 1 addition & 5 deletions packages/cli/src/core/security/secretDetectors.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { shannonEntropyNormalized } from './entropy.js';
import { isLikelyMinified } from '../helpers/isLikelyMinified.js';

/**
* Severity levels for detected secrets
Expand Down Expand Up @@ -55,11 +56,6 @@ const HARMLESS_URLS = [
const HARMLESS_ATTRIBUTE_KEYS =
/\b(trackingId|trackingContext|data-testid|data-test|aria-label)\b/i;

// Ignore minified files
function isLikelyMinified(line: string): boolean {
return line.length > 500; // Extremely long line, likely minified
}

// Checks if a line is an HTML text node or tag
function isHtmlTextNode(line: string): boolean {
const trimmed = line.trim();
Expand Down
2 changes: 2 additions & 0 deletions packages/cli/src/services/scanCodebase.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { DEFAULT_EXCLUDE_PATTERNS } from '../core/scan/patterns.js';
import { scanFile } from '../core/scan/scanFile.js';
import { findFiles } from './fileWalker.js';
import { normalizePath } from '../core/helpers/normalizePath.js';
import { isLikelyMinified } from '../core/helpers/isLikelyMinified.js';

/**
* Scans the codebase for environment variable usage based on the provided options.
Expand All @@ -30,6 +31,7 @@ export async function scanCodebase(opts: ScanOptions): Promise<ScanResult> {
for (const filePath of files) {
const content = await safeReadFile(filePath);
if (!content) continue;
if (isLikelyMinified(content)) continue; // Skip likely minified files

// Scan the file for environment variable usages
const fileUsages = scanFile(filePath, content, opts);
Expand Down
14 changes: 14 additions & 0 deletions packages/cli/test/unit/core/scan/scanFile.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,20 @@ const key = process.env.SECRET_KEY;`;
expect(usages[0]?.isLogged).toBe(true);
});

it('ignores env usage on likely minified lines', () => {
const minifiedLine = `${'x'.repeat(520)}process.env.API_KEY`;
const usages = scanFile('/test/project/src/app.js', minifiedLine, baseOpts);

expect(usages).toHaveLength(0);
});

it('ignores console.log env usage on likely minified lines', () => {
const minifiedLine = `${'x'.repeat(520)}console.log(process.env.API_KEY)`;
const usages = scanFile('/test/project/src/app.js', minifiedLine, baseOpts);

expect(usages).toHaveLength(0);
});

it('does not mark as logged when not in console statement', () => {
const content = 'const key = process.env.API_KEY;';
const usages = scanFile('/test/project/src/app.js', content, baseOpts);
Expand Down