From ad0ee05841dd80cf035ad33270616b0f1fafc4ec Mon Sep 17 00:00:00 2001 From: Chrilleweb Date: Thu, 16 Apr 2026 21:53:47 +0200 Subject: [PATCH 1/3] chore(docs): added security docs --- docs/security_scanner.md | 139 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 139 insertions(+) create mode 100644 docs/security_scanner.md diff --git a/docs/security_scanner.md b/docs/security_scanner.md new file mode 100644 index 0000000..04e4f27 --- /dev/null +++ b/docs/security_scanner.md @@ -0,0 +1,139 @@ +# Security Scanner + +`dotenv-diff` scans your source files and `.env.example` for hardcoded secrets using three complementary techniques. + +## Table of Contents + +- [Provider Pattern Matching](#1-provider-pattern-matching-high-severity) +- [Suspicious Key Name Detection](#2-suspicious-key-name-detection-medium-severity) +- [High-Entropy String Detection](#3-high-entropy-string-detection-medium--high-severity) +- [Hardcoded HTTPS URLs](#4-hardcoded-https-urls-low-severity) +- [Example File Scanning](#example-file-scanning) +- [False Positive Protections](#false-positive-protections) +- [Suppressing False Positives](#suppressing-false-positives) + +--- + +## 1. Provider Pattern Matching (high severity) + +Detects known credential formats from popular providers: + +| Provider | Example pattern | +|---|---| +| AWS access key | `AKIA` + 16 uppercase alphanumeric chars | +| AWS temporary key | `ASIA` + 16 uppercase alphanumeric chars | +| GitHub token | `ghp_` + 30+ alphanumeric chars | +| Stripe live secret | `sk_live_` + 24+ alphanumeric chars | +| Stripe test secret | `sk_test_` + 24+ alphanumeric chars | +| Google API key | `AIza` + 20+ alphanumeric chars | +| Google OAuth token | `ya29.` + alphanumeric chars | +| Firebase token | 21-char ID + `:` + 140-char token | +| JWT | Three base64url segments separated by `.` starting with `eyJ` | +| Twilio Account SID | `AC` + 32 hex chars | +| Ethereum address | `0x` + 40 hex chars | + +--- + +## 2. Suspicious Key Name Detection (medium severity) + +Flags literal string assignments where the variable or attribute name matches a sensitive pattern: + +``` +password, pass, secret, token, apikey, api_key, client_secret, access_token, access-token +``` + +Only triggers when all of the following are true: + +- The value is **12+ characters** long +- The value does **not** contain spaces (space → likely a human-readable label, not a secret) +- The attribute name is **not** a known harmless UI prop (`label`, `placeholder`, `name`, `title`, `aria-label`, etc.) +- The line does **not** read from an env accessor (`process.env`, `import.meta.env`, SvelteKit `$env/*`) +- The value is **not** a pure interpolation template (e.g. `` `${a}:${b}` ``) + +--- + +## 3. High-Entropy String Detection (medium / high severity) + +Uses [Shannon entropy](https://en.wikipedia.org/wiki/Entropy_(information_theory)) to detect randomly-generated secrets — strings that are statistically too random to be written by hand. + +| String length | Entropy threshold | Severity | +|---|---|---| +| 32–47 chars | ≥ 0.85 (normalized) | medium | +| 48+ chars | ≥ 0.85 (normalized) | high | + +> In test files (`*.spec.ts`, `*.test.ts`, `__tests__/`, `fixtures/`, etc.) the threshold is raised to **0.95** to reduce false positives. + +--- + +## 4. Hardcoded HTTPS URLs (low severity) + +Flags HTTPS URLs embedded as string literals, suggesting they should be moved to an environment variable. + +The following are **ignored automatically**: + +- `example.com`, `placeholder.com` +- `127.0.0.1` +- SVG namespace URIs (`http://www.w3.org/2000/svg`) + +Additional URLs can be ignored via the `--ignore-urls` flag — see [Configuration and Flags](./configuration_and_flags.md). + +--- + +## Example File Scanning + +`.env.example` files are scanned separately with relaxed rules, since example files are expected to contain placeholder values. Entries are skipped when the value: + +- Is empty +- Equals `example` or `placeholder` (case-insensitive) +- Contains `your_` or `CHANGE_ME` +- Contains `<` (typical for `` style templates) + +Remaining values are still checked against [provider patterns](#1-provider-pattern-matching-high-severity) and entropy (threshold ≥ 0.8 for values ≥ 24 characters). + +--- + +## False Positive Protections + +The scanner automatically skips values that are clearly not secrets: + +| Pattern | Example | +|---|---| +| UUIDs | `550e8400-e29b-41d4-a716-446655440000` | +| Hex hashes | MD5, SHA-1, SHA-256 (32–128 hex chars) | +| Short base64 IDs | 16–20 char base64 strings | +| Data URIs | `data:image/png;base64,...` | +| Relative paths | `./assets/image.png` | +| SVG path data | `M10 20 L30 40 Z` | +| Character set literals | `abcdefghijklmnopqrstuvwxyz0123456789` (used with `nanoid` etc.) | +| UI label strings | Any value containing spaces | +| Minified lines | Lines over 500 characters are skipped entirely | +| Comment-only lines | Lines starting with `//` | +| Env accessors | `process.env.MY_KEY`, `import.meta.env.MY_KEY` | + +--- + +## Suppressing False Positives + +If a finding is a known false positive, suppress it with an ignore comment on the same line. + +### Single line + +```typescript +const apiKey = 'safe_value_for_tests_123123'; // dotenv-diff-ignore +``` + +```html + +``` + +### Block + +```html + + + +``` + +Ignore markers are **case-insensitive** and support `//`, `/* */`, and `` comment styles. + +For broader suppression across files or URL patterns, see [Ignore Comments](./ignore_comments.md) and [Configuration and Flags](./configuration_and_flags.md). From 0a93e66376349ef18f3f96ea22ca396ba004409d Mon Sep 17 00:00:00 2001 From: Chrilleweb Date: Sat, 18 Apr 2026 17:15:08 +0200 Subject: [PATCH 2/3] chore: updated docs --- docs/security_scanner.md | 15 --------------- packages/cli/src/core/helpers/isLikelyMinified.ts | 2 ++ 2 files changed, 2 insertions(+), 15 deletions(-) diff --git a/docs/security_scanner.md b/docs/security_scanner.md index 04e4f27..6be2943 100644 --- a/docs/security_scanner.md +++ b/docs/security_scanner.md @@ -7,7 +7,6 @@ - [Provider Pattern Matching](#1-provider-pattern-matching-high-severity) - [Suspicious Key Name Detection](#2-suspicious-key-name-detection-medium-severity) - [High-Entropy String Detection](#3-high-entropy-string-detection-medium--high-severity) -- [Hardcoded HTTPS URLs](#4-hardcoded-https-urls-low-severity) - [Example File Scanning](#example-file-scanning) - [False Positive Protections](#false-positive-protections) - [Suppressing False Positives](#suppressing-false-positives) @@ -65,20 +64,6 @@ Uses [Shannon entropy](https://en.wikipedia.org/wiki/Entropy_(information_theory --- -## 4. Hardcoded HTTPS URLs (low severity) - -Flags HTTPS URLs embedded as string literals, suggesting they should be moved to an environment variable. - -The following are **ignored automatically**: - -- `example.com`, `placeholder.com` -- `127.0.0.1` -- SVG namespace URIs (`http://www.w3.org/2000/svg`) - -Additional URLs can be ignored via the `--ignore-urls` flag — see [Configuration and Flags](./configuration_and_flags.md). - ---- - ## Example File Scanning `.env.example` files are scanned separately with relaxed rules, since example files are expected to contain placeholder values. Entries are skipped when the value: diff --git a/packages/cli/src/core/helpers/isLikelyMinified.ts b/packages/cli/src/core/helpers/isLikelyMinified.ts index e262a0b..c67d82c 100644 --- a/packages/cli/src/core/helpers/isLikelyMinified.ts +++ b/packages/cli/src/core/helpers/isLikelyMinified.ts @@ -1,6 +1,8 @@ /** * Returns true if a line looks like minified/bundled code. * Used to skip entire files early in the pipeline. + * @param content - The content of the file to check + * @returns Boolean whether the content is likely minified */ export function isLikelyMinified(content: string): boolean { return content.split(/\r?\n/).some((line) => line.length > 500); From fcc8c65c440a48aa62aabc922d225a71d03745f6 Mon Sep 17 00:00:00 2001 From: Chrilleweb Date: Sat, 18 Apr 2026 18:39:38 +0200 Subject: [PATCH 3/3] chore: updated docs --- docs/capabilities.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/capabilities.md b/docs/capabilities.md index 7b79718..fe31871 100644 --- a/docs/capabilities.md +++ b/docs/capabilities.md @@ -54,15 +54,15 @@ Duplicate variable definitions inside env files (both main env and example env, ### 4 Secret Detection -Potential secrets and sensitive values, including high-risk patterns. +Potential secrets and sensitive values, including high-risk patterns. See [Security Scanner](./security_scanner.md) for a full description of detection techniques and false positive protections. ### 5 Example File Secret Warnings -Potential secrets found in `.env.example` content. +Potential secrets found in `.env.example` content. See the [Example File Scanning](./security_scanner.md#example-file-scanning) section of the Security Scanner docs. ### 6 Framework-Specific Misuse -Framework-aware warnings (for supported frameworks) around unsafe or incorrect env usage patterns. +Framework-aware warnings (for supported frameworks) around unsafe or incorrect env usage patterns. See [Framework Warnings](./frameworks/index.md). ### 7 Uppercase Naming Warnings @@ -78,7 +78,7 @@ Cases where environment-related values are logged with `console.log`. ### 10 Expiration Warnings -Warnings for environment values that look like expiring tokens/credentials or contain expiration metadata. +Warnings for environment values that look like expiring tokens/credentials or contain expiration metadata. See [Expiration Warnings](./expiration_warnings.md). ### 11 Gitignore Safety Check