"use strict";
/**
 * Layer 2: Variable Heuristics
 * Identifies variable names associated with sensitive data
 */
Object.defineProperty(exports, "__esModule", { value: true });
exports.SENSITIVE_VARIABLE_PATTERNS = void 0;
exports.detectSensitiveVariables = detectSensitiveVariables;
const context_helpers_1 = require("../utils/context-helpers");
// Patterns for sensitive variable names
exports.SENSITIVE_VARIABLE_PATTERNS = [
    // Password-related
    {
        pattern: /\b(password|passwd|pwd|pass)\s*[=:]/gi,
        severity: 'high',
        description: 'Variable name suggests password storage',
    },
    {
        pattern: /\b(user_?password|admin_?password|db_?password|database_?password)\s*[=:]/gi,
        severity: 'critical',
        description: 'Variable name suggests database/admin password',
    },
    // Token-related
    {
        pattern: /\b(auth_?token|access_?token|refresh_?token|bearer_?token)\s*[=:]/gi,
        severity: 'high',
        description: 'Variable name suggests authentication token',
    },
    {
        pattern: /\b(api_?token|api_?key|apikey)\s*[=:]/gi,
        severity: 'high',
        description: 'Variable name suggests API key/token',
    },
    // Secret-related
    {
        pattern: /\b(secret|secret_?key|private_?key|signing_?key)\s*[=:]/gi,
        severity: 'high',
        description: 'Variable name suggests secret/private key',
    },
    {
        pattern: /\b(client_?secret|app_?secret|jwt_?secret)\s*[=:]/gi,
        severity: 'critical',
        description: 'Variable name suggests application secret',
    },
    // Credential-related
    {
        pattern: /\b(credential|credentials|creds)\s*[=:]/gi,
        severity: 'high',
        description: 'Variable name suggests credentials',
    },
    // Connection strings
    {
        pattern: /\b(connection_?string|conn_?string|database_?url|db_?url)\s*[=:]/gi,
        severity: 'high',
        description: 'Variable name suggests database connection string',
    },
    // Encryption keys
    {
        pattern: /\b(encryption_?key|decrypt_?key|cipher_?key|aes_?key)\s*[=:]/gi,
        severity: 'critical',
        description: 'Variable name suggests encryption key',
    },
    // SSH/Certificate
    {
        pattern: /\b(ssh_?key|private_?key|cert_?key|ssl_?key)\s*[=:]/gi,
        severity: 'critical',
        description: 'Variable name suggests SSH/SSL key',
    },
];
// Check if the value looks like a placeholder or env var reference
function isPlaceholderOrEnvRef(line) {
    const safePatterns = [
        /[=:]\s*['"]?\s*$/, // Empty value
        /[=:]\s*['"]?xxx/i, // xxx placeholder
        /[=:]\s*['"]?your[-_]/i, // your-xxx placeholder
        /[=:]\s*['"]?<[^>]+>/, // <placeholder>
        /[=:]\s*['"]?\$\{/, // ${VAR} template
        /[=:]\s*['"]?process\.env/, // process.env reference
        /[=:]\s*['"]?env\(/, // env() function
        /[=:]\s*['"]?getenv/i, // getenv function
        /[=:]\s*['"]?os\.environ/, // Python os.environ
        /[=:]\s*['"]?ENV\[/, // Ruby ENV
        /[=:]\s*null\b/i, // null value
        /[=:]\s*undefined\b/, // undefined value
        /[=:]\s*None\b/, // Python None
        /[=:]\s*['"]?TODO/i, // TODO placeholder
        /[=:]\s*['"]?CHANGEME/i, // CHANGEME placeholder
        /[=:]\s*['"]?REPLACE/i, // REPLACE placeholder
        /\?\s*.*\s*:\s*/, // Ternary operator (conditional assignment)
        /\|\|/, // OR fallback (e.g., ENV_VAR || '')
        /\?\?/, // Nullish coalescing
        /[A-Z_]{3,}_(?:KEY|TOKEN|SECRET)/, // References to env var constants
    ];
    return safePatterns.some(pattern => pattern.test(line));
}
// Check if line is a comment
function isComment(line) {
    const trimmed = line.trim();
    return (trimmed.startsWith('//') ||
        trimmed.startsWith('#') ||
        trimmed.startsWith('*') ||
        trimmed.startsWith('/*') ||
        trimmed.startsWith('"""') ||
        trimmed.startsWith("'''") ||
        trimmed.startsWith('<!--'));
}
// Check if it's a type definition or interface
function isTypeDefinition(line) {
    return (/^\s*(type|interface|class)\s/.test(line) ||
        /:\s*(string|number|boolean|any)\s*[;,}]/.test(line) ||
        /\?\s*:\s*\w+/.test(line));
}
function detectSensitiveVariables(content, filePath, options) {
    const vulnerabilities = [];
    // Skip scanner/fixture files to avoid self-detection
    if ((0, context_helpers_1.isScannerOrFixtureFile)(filePath))
        return vulnerabilities;
    const lines = options?.parsed?.lines ?? content.split('\n');
    lines.forEach((line, index) => {
        // Skip comments
        if (isComment(line))
            return;
        // Skip type definitions
        if (isTypeDefinition(line))
            return;
        // Skip if it's a placeholder/env reference
        if (isPlaceholderOrEnvRef(line))
            return;
        for (const pattern of exports.SENSITIVE_VARIABLE_PATTERNS) {
            const regex = new RegExp(pattern.pattern.source, pattern.pattern.flags);
            if (regex.test(line)) {
                // Extract the actual value to check if it's hardcoded
                const valueMatch = line.match(/[=:]\s*['"]([^'"]+)['"]/i);
                if (valueMatch && valueMatch[1].length > 3) {
                    // Has a non-trivial hardcoded value
                    vulnerabilities.push({
                        id: `var-${filePath}-${index + 1}`,
                        filePath,
                        lineNumber: index + 1,
                        lineContent: line.trim(),
                        severity: pattern.severity,
                        category: 'sensitive_variable',
                        title: 'Sensitive variable with hardcoded value',
                        description: pattern.description + '. The value appears to be hardcoded rather than loaded from environment.',
                        suggestedFix: 'Move this sensitive value to an environment variable or secure secrets manager.',
                        confidence: 'medium',
                        layer: 2,
                    });
                }
                break; // Only report once per line
            }
        }
    });
    return vulnerabilities;
}
//# sourceMappingURL=variables.js.map