Envark’s risk analysis engine evaluates environment variables for security vulnerabilities, configuration issues, and best practice violations. It uses a multi-factor scoring system to classify risks and provides actionable recommendations.
Envark calculates a risk score (0-5) using multiple factors:
// From src/core/analyzer.ts:99-129function calculateRiskScore(variable: EnvVariable): number { let score = 0; // Critical: Used but never defined anywhere and no default if (variable.usedInCode && !variable.definedInEnvFile && !variable.hasDefault) { score += 5; } // High: Defined in .env but not in .env.example (potential secret leak) if (variable.definedInEnvFile && !variable.definedInExample && looksLikeSecret(variable.name)) { score += 4; } // Medium: Used in multiple files with no default if (variable.usedInCode && variable.usages.length > 2 && !variable.hasDefault) { score += 3; } // Low: Not documented if (!variable.isDocumented && variable.usedInCode) { score += 1; } // Low: Dead variable (defined but never used) if (variable.definedInEnvFile && !variable.usedInCode) { score += 1; } return Math.min(score, 5);}
Severity: CriticalVariable is used in code but not defined anywhere.
// code.tsconst apiKey = process.env.API_KEY; // ✗ API_KEY not in any .env file
Risk: Application will receive undefined, potentially causing runtime errors or security issues.Recommendation: Add the variable to your .env file or provide a default value in code.
# .envAPI_KEY=your_api_key_here
Severity: HighSecret-like variable defined in a potentially committed .env file.
# .env (might be committed!)DATABASE_PASSWORD=super_secret_123SECRET_KEY=my-secret-key
Risk: Credentials may be exposed in version control.Detection Logic:
// From src/core/analyzer.ts:222-237if (looksLikeSecret(variable.name) && variable.definedInEnvFile) { // Check if it's in a committed file (not .env.local) const inCommittedFile = variable.definitions.some(d => { const path = d.relativePath.toLowerCase(); return path === '.env' || path.endsWith('/.env'); }); if (inCommittedFile) { issues.push({ type: 'EXPOSED', severity: 'high', message: `${variable.name} looks like a secret but is in a potentially committed .env file`, recommendation: `Move ${variable.name} to .env.local or ensure .env is in .gitignore` }); }}
Recommendation:
Move secrets to .env.local (git-ignored)
Ensure .env is in .gitignore
Use secret management tools (Vault, AWS Secrets Manager)
Severity: MediumVariable has different values across multiple .env files.
# .envAPI_URL=https://prod.example.com# .env.developmentAPI_URL=http://localhost:3000# .env.localAPI_URL=https://staging.example.com # ⚠ Three different values
Risk: Confusion about which value is active, potential for using wrong configuration.Recommendation: Document why values differ or consolidate to environment-specific files.
Severity: MediumVariable contains an obvious placeholder that should be replaced.
Recommendation: Replace with actual production values before deployment.
Severity: MediumVariable names that are similar and may represent the same configuration.
// Different files using similar namesprocess.env.DATABASE_URL // config.tsprocess.env.DB_URL // db.tsprocess.env.MONGO_URL // mongo.ts
Risk: Team confusion, potential for misconfiguration.Recommendation: Standardize variable naming across the codebase.
Severity: MediumVariable used in multiple places with no fallback value.
// Multiple usages without defaultsconst port = process.env.PORT; // ✗ No defaultconst host = process.env.HOST; // ✗ No default// Better approachconst port = process.env.PORT || 3000; // ✓ Has default
Risk: Undefined behavior if variable is not set.Recommendation: Add default values or validate at startup.
Severity: LowVariable is not in .env.example and has no documentation.
# .envNEW_FEATURE_FLAG=true # ✗ Not in .env.example
Risk: New team members won’t know this variable exists.Recommendation:
# .env.example# Enable the new feature (true/false)NEW_FEATURE_FLAG=false
Severity: LowVariable is defined in .env files but never used in code.
# .envOLD_API_KEY=abc123 # ✗ No references in code
Risk: Configuration clutter, confusion about what’s needed.Recommendation: Remove unused variables or verify they’re needed for indirect usage.
Severity: LowVariable is defined with an empty value.
# .envOPTIONAL_FEATURE=DEBUG_MODE=""
Risk: May cause unexpected behavior if code doesn’t handle empty strings.Recommendation: Set an actual value or remove the variable.
┌─ RISK ANALYSIS ───────────────────────────────────────────┐│ Critical: 2 High: 5 Medium: 12 Low: 23└──────────────────────────────────────────────────────────┘ ⚠ DATABASE_PASSWORD [CRITICAL] → Used in code but not defined in any .env file → Add DATABASE_PASSWORD to your .env file or provide a default value ⚠ SECRET_KEY [HIGH] → Looks like a secret but is in a potentially committed .env file → Move SECRET_KEY to .env.local or ensure .env is in .gitignore ⚠ API_URL [MEDIUM] → Has different values across .env files → .env: "https://prod.example.com" → .env.local: "http://localhost:3000"