csp-security-project / js /advanced-vulnerability-detector.js
AbdulElahGwaith's picture
Upload folder using huggingface_hub
d0a2071 verified
/**
* Advanced Vulnerability Detection System
* NLP-powered vulnerability detection with pattern recognition and machine learning
* Author: MiniMax Agent
* Date: 2025-12-10
*/
class AdvancedVulnerabilityDetector {
constructor() {
this.nlpEngine = new NLPVulnerabilityEngine();
this.patternRecognizer = new AdvancedPatternRecognizer();
this.mlClassifier = new MLVulnerabilityClassifier();
this.semanticAnalyzer = new SemanticCodeAnalyzer();
this.contextAnalyzer = new ContextualAnalyzer();
this.initialized = false;
this.detectionCache = new Map();
this.learningData = [];
}
async initialize() {
try {
console.log('🔍 Initializing Advanced Vulnerability Detector...');
// Initialize NLP engine
await this.nlpEngine.initialize();
// Initialize pattern recognition
await this.patternRecognizer.initialize();
// Initialize ML classifier
await this.mlClassifier.initialize();
// Initialize semantic analyzer
await this.semanticAnalyzer.initialize();
// Initialize context analyzer
await this.contextAnalyzer.initialize();
// Load vulnerability knowledge base
await this.loadVulnerabilityKnowledgeBase();
// Setup real-time monitoring
this.setupRealTimeDetection();
this.initialized = true;
console.log('✅ Advanced Vulnerability Detector initialized successfully');
} catch (error) {
console.error('❌ Failed to initialize Advanced Vulnerability Detector:', error);
throw error;
}
}
async loadVulnerabilityKnowledgeBase() {
this.vulnerabilityPatterns = {
sql_injection: {
patterns: [
/union\s+select/gi,
/['"]\s*or\s*['"]1['"]\s*=\s*['"]1['"]/gi,
/\b(drop|delete|update|insert)\s+table/gi,
/\b(exec|execute)\s*\(/gi,
/--\s*$/gm,
/\bshutdown\b/gi,
/\b xp_cmdshell \b/gi
],
semantic: {
keywords: ['sql', 'database', 'query', 'select', 'insert', 'update', 'delete'],
context: ['user_input', 'parameter', 'request', 'form'],
severity: 9
},
variants: [
'union-based injection',
'boolean-based injection',
'time-based injection',
'error-based injection',
'stacked queries injection'
]
},
xss: {
patterns: [
/<script\b[^>]*>.*?<\/script>/gi,
/<iframe\b[^>]*>/gi,
/\bon\w+\s*=\s*["'][^"']*["']/gi,
/javascript:/gi,
/\beval\s*\(/gi,
/\bdocument\.(cookie|location)\b/gi,
/\bwindow\.(location|open)\b/gi
],
semantic: {
keywords: ['html', 'script', 'javascript', 'event', 'onclick', 'onload'],
context: ['output', 'display', 'render', 'innerHTML', 'document.write'],
severity: 8
},
variants: [
'reflected XSS',
'stored XSS',
'DOM-based XSS',
'mXSS (mutated XSS)',
'Universal XSS (UXSS)'
]
},
command_injection: {
patterns: [
/[;&|`$]\s*(?:ls|cat|rm|mkdir|chmod|chown|wget|curl|nc|netcat|telnet|ssh)/gi,
/\bexec\s*\(\s*\$_(?:GET|POST|REQUEST)\[/gi,
/\bshell_exec\s*\(/gi,
/\bsystem\s*\(/gi,
/\bpopen\s*\(/gi,
/`[^`]*`/gi
],
semantic: {
keywords: ['exec', 'system', 'shell', 'command', 'bash', 'cmd'],
context: ['system', 'shell', 'os', 'command', 'execute'],
severity: 10
},
variants: [
'OS Command Injection',
'Shell Injection',
'Code Injection',
'LDAP Injection',
'XPath Injection'
]
},
path_traversal: {
patterns: [
/\.\.[\/\\]/gi,
/%2e%2e%2f/gi,
/%252e%252e%252f/gi,
/\.\.%2f/gi,
/etc\/passwd/gi,
/boot\.ini/gi,
/windows\/system32/gi
],
semantic: {
keywords: ['path', 'file', 'directory', 'folder', 'read', 'open'],
context: ['file_path', 'directory', 'include', 'require', 'import'],
severity: 8
},
variants: [
'Directory Traversal',
'Path Traversal',
'File Inclusion',
'Null Byte Injection',
'Unicode Traversal'
]
},
csrf: {
patterns: [
/<form[^>]*method\s*=\s*["']?(?:post|put|delete)["']?[^>]*>/gi,
/\b(csrf_token|xsrf_token)\b/gi,
/\breferer\s*=/gi,
/\borigin\s*=/gi,
/\bwithCredentials\s*=/gi
],
semantic: {
keywords: ['form', 'post', 'token', 'validate', 'verify'],
context: ['form', 'request', 'action', 'submit', 'method'],
severity: 7
},
variants: [
'Login CSRF',
'Session Fixation',
'Cross-Site Request Forgery',
'One-Click Attack',
'Smart CSRF'
]
},
deserialization: {
patterns: [
/\b(unserialize|json_decode|yaml_parse|pickle_loads)\s*\(/gi,
/\bphar:\/\//gi,
/O:\d+:/gi,
/a:\d+:/gi,
/\b@eval\s*\(/gi,
/\b__wakeup\b/gi,
/\b__destruct\b/gi
],
semantic: {
keywords: ['serialize', 'deserialize', 'pickle', 'unserialize', 'object'],
context: ['object', 'class', 'method', 'function', 'callback'],
severity: 9
},
variants: [
'PHP Deserialization',
'Python Pickle Injection',
'Java Deserialization',
'.NET Deserialization',
'Ruby YAML Deserialization'
]
},
server_side_request_forgery: {
patterns: [
/\b(file_get_contents|curl_exec|wget|fsockopen)\s*\(\s*\$_(?:GET|POST|REQUEST)/gi,
/\b(urlopen|urlretrieve)\s*\(/gi,
/\b(HttpRequest|WebClient)\s*\(/gi,
/https?:\/\/localhost/gi,
/file:\/\//gi,
/dict:\/\//gi
],
semantic: {
keywords: ['request', 'url', 'fetch', 'get', 'download', 'include'],
context: ['http', 'request', 'url', 'fetch', 'download'],
severity: 9
},
variants: [
'Basic SSRF',
'Blind SSRF',
'Semi-Blind SSRF',
'XXE (XML External Entity)',
'Open Redirect'
]
}
};
}
async analyzeCode(code, options = {}) {
if (!this.initialized) {
await this.initialize();
}
const analysisId = this.generateAnalysisId(code);
// Check cache first
if (this.detectionCache.has(analysisId) && !options.force) {
console.log('📋 Returning cached analysis result');
return this.detectionCache.get(analysisId);
}
console.log('🔍 Starting comprehensive vulnerability analysis...');
const analysisResults = {
id: analysisId,
timestamp: Date.now(),
code: code,
vulnerabilities: [],
riskScore: 0,
confidence: 0,
recommendations: [],
analysisTime: 0,
methods: []
};
const startTime = performance.now();
try {
// Multi-method analysis
const [
patternResults,
semanticResults,
contextualResults,
mlResults,
nlpResults
] = await Promise.allSettled([
this.patternRecognizer.analyze(code, this.vulnerabilityPatterns),
this.semanticAnalyzer.analyze(code),
this.contextAnalyzer.analyze(code),
this.mlClassifier.classify(code),
this.nlpEngine.analyze(code)
]);
// Process results
if (patternResults.status === 'fulfilled') {
analysisResults.vulnerabilities.push(...patternResults.value);
analysisResults.methods.push('pattern_recognition');
}
if (semanticResults.status === 'fulfilled') {
analysisResults.vulnerabilities.push(...semanticResults.value);
analysisResults.methods.push('semantic_analysis');
}
if (contextualResults.status === 'fulfilled') {
analysisResults.vulnerabilities.push(...contextualResults.value);
analysisResults.methods.push('contextual_analysis');
}
if (mlResults.status === 'fulfilled') {
analysisResults.vulnerabilities.push(...mlResults.value);
analysisResults.methods.push('machine_learning');
}
if (nlpResults.status === 'fulfilled') {
analysisResults.vulnerabilities.push(...nlpResults.value);
analysisResults.methods.push('nlp_analysis');
}
// Deduplicate vulnerabilities
analysisResults.vulnerabilities = this.deduplicateVulnerabilities(
analysisResults.vulnerabilities
);
// Calculate overall risk score
analysisResults.riskScore = this.calculateRiskScore(analysisResults.vulnerabilities);
// Calculate confidence
analysisResults.confidence = this.calculateConfidence(analysisResults);
// Generate recommendations
analysisResults.recommendations = this.generateRecommendations(
analysisResults.vulnerabilities
);
const endTime = performance.now();
analysisResults.analysisTime = endTime - startTime;
// Cache results
this.detectionCache.set(analysisId, analysisResults);
// Store for learning
this.learningData.push({
code: code,
vulnerabilities: analysisResults.vulnerabilities,
timestamp: Date.now()
});
console.log(`✅ Analysis completed in ${analysisResults.analysisTime.toFixed(2)}ms`);
return analysisResults;
} catch (error) {
console.error('Analysis failed:', error);
throw new Error(`Vulnerability analysis failed: ${error.message}`);
}
}
deduplicateVulnerabilities(vulnerabilities) {
const seen = new Set();
return vulnerabilities.filter(vuln => {
const key = `${vuln.type}-${vuln.line}-${vuln.startColumn}-${vuln.endColumn}`;
if (seen.has(key)) {
return false;
}
seen.add(key);
return true;
});
}
calculateRiskScore(vulnerabilities) {
if (vulnerabilities.length === 0) return 0;
const weightedScore = vulnerabilities.reduce((score, vuln) => {
const baseScore = vuln.severity || 5;
const confidenceMultiplier = vuln.confidence || 0.5;
const contextMultiplier = vuln.contextScore || 1;
return score + (baseScore * confidenceMultiplier * contextMultiplier);
}, 0);
return Math.min(100, weightedScore);
}
calculateConfidence(analysisResults) {
const methodCount = analysisResults.methods.length;
const vulnerabilityCount = analysisResults.vulnerabilities.length;
const avgConfidence = analysisResults.vulnerabilities.reduce(
(sum, vuln) => sum + (vuln.confidence || 0.5), 0
) / Math.max(vulnerabilityCount, 1);
// Higher confidence with multiple methods agreeing
const methodBonus = Math.min(0.3, (methodCount - 1) * 0.1);
return Math.min(0.99, avgConfidence + methodBonus);
}
generateRecommendations(vulnerabilities) {
const recommendations = [];
const vulnTypes = [...new Set(vulnerabilities.map(v => v.type))];
for (const vulnType of vulnTypes) {
const vulnGroup = vulnerabilities.filter(v => v.type === vulnType);
const maxSeverity = Math.max(...vulnGroup.map(v => v.severity || 5));
switch (vulnType) {
case 'sql_injection':
recommendations.push({
type: 'SQL Injection Prevention',
priority: maxSeverity >= 8 ? 'Critical' : 'High',
actions: [
'Use parameterized queries for all database operations',
'Implement input validation and sanitization',
'Use ORM frameworks when possible',
'Apply principle of least privilege for database accounts'
],
code: `// Safe example
const query = 'SELECT * FROM users WHERE id = ? AND password_hash = ?';
const result = db.execute(query, [userId, passwordHash]);`
});
break;
case 'xss':
recommendations.push({
type: 'XSS Prevention',
priority: maxSeverity >= 8 ? 'Critical' : 'High',
actions: [
'Implement Content Security Policy (CSP)',
'Use output encoding for all user data',
'Avoid innerHTML for user content',
'Use textContent instead of innerHTML',
'Validate and sanitize all inputs'
],
code: `// Safe example
element.textContent = userInput; // Instead of element.innerHTML = userInput
// CSP header
Content-Security-Policy: default-src 'self'; script-src 'self';`
});
break;
case 'command_injection':
recommendations.push({
type: 'Command Injection Prevention',
priority: 'Critical',
actions: [
'Avoid shell command execution with user input',
'Use APIs instead of system calls when possible',
'Implement strict input validation',
'Use allowlists instead of blocklists',
'Escape shell metacharacters'
],
code: `// Safe example - avoid
// system("ls " + userInput); // UNSAFE
// Instead use
const allowedCommands = ['list', 'info', 'status'];
if (allowedCommands.includes(userInput)) {
executeCommand(userInput);
}`
});
break;
case 'csrf':
recommendations.push({
type: 'CSRF Prevention',
priority: 'High',
actions: [
'Implement CSRF tokens for all state-changing operations',
'Use SameSite cookies',
'Validate Referer and Origin headers',
'Use POST for state-changing operations',
'Implement rate limiting'
],
code: `// Safe example
// Generate CSRF token
const csrfToken = generateSecureToken();
// Include in forms
<form method="POST">
<input type="hidden" name="csrf_token" value="${csrfToken}">
</form>
// Validate on server
if (!validateCSRFToken(request.csrf_token, session.csrf_token)) {
throw new Error('Invalid CSRF token');
}`
});
break;
case 'deserialization':
recommendations.push({
type: 'Deserialization Prevention',
priority: 'Critical',
actions: [
'Avoid deserializing untrusted data',
'Use safe serialization formats (JSON)',
'Implement integrity checks',
'Validate object types before deserialization',
'Use type-safe deserialization libraries'
],
code: `// Safe example
// Instead of unsafe deserialization
// unserialize(userInput); // UNSAFE
// Use JSON
const data = JSON.parse(userInput); // Safe
// For PHP, use safe deserialization
$object = Symfony\Component\Yaml\Yaml::parse($userInput);`
});
break;
}
}
return recommendations;
}
generateAnalysisId(code) {
return 'analysis_' + this.simpleHash(code);
}
simpleHash(str) {
let hash = 0;
for (let i = 0; i < str.length; i++) {
const char = str.charCodeAt(i);
hash = ((hash << 5) - hash) + char;
hash = hash & hash; // Convert to 32bit integer
}
return Math.abs(hash).toString(36);
}
setupRealTimeDetection() {
// Monitor for new vulnerabilities in real-time
if (typeof window !== 'undefined') {
// Monitor DOM changes
const observer = new MutationObserver((mutations) => {
mutations.forEach((mutation) => {
mutation.addedNodes.forEach((node) => {
if (node.nodeType === Node.ELEMENT_NODE) {
this.analyzeElement(node);
}
});
});
});
observer.observe(document.body, {
childList: true,
subtree: true
});
// Monitor script injection
const originalCreateElement = document.createElement;
document.createElement = function(tagName) {
const element = originalCreateElement.call(this, tagName);
if (tagName.toLowerCase() === 'script') {
this.analyzeElement(element);
}
return element;
};
}
}
async analyzeElement(element) {
const html = element.outerHTML || '';
if (html.length > 0) {
try {
const results = await this.analyzeCode(html, { force: true });
if (results.vulnerabilities.length > 0) {
console.warn('🚨 Real-time vulnerability detected:', results.vulnerabilities);
this.handleRealTimeVulnerability(results);
}
} catch (error) {
// Silent fail for real-time analysis
}
}
}
handleRealTimeVulnerability(results) {
// Dispatch custom event for real-time vulnerability detection
if (typeof window !== 'undefined' && window.dispatchEvent) {
window.dispatchEvent(new CustomEvent('vulnerabilityDetected', {
detail: results
}));
}
}
// Public API methods
async getVulnerabilityPatterns() {
return this.vulnerabilityPatterns;
}
async getAnalysisHistory() {
return Array.from(this.detectionCache.values());
}
async exportResults(format = 'json') {
const results = Array.from(this.detectionCache.values());
switch (format) {
case 'json':
return JSON.stringify(results, null, 2);
case 'csv':
return this.convertToCSV(results);
case 'html':
return this.convertToHTML(results);
default:
return JSON.stringify(results, null, 2);
}
}
convertToCSV(results) {
const headers = ['ID', 'Timestamp', 'Risk Score', 'Confidence', 'Vulnerabilities', 'Methods'];
const rows = results.map(result => [
result.id,
new Date(result.timestamp).toISOString(),
result.riskScore,
result.confidence,
result.vulnerabilities.length,
result.methods.join(';')
]);
return [headers, ...rows].map(row => row.join(',')).join('\n');
}
convertToHTML(results) {
let html = `
<!DOCTYPE html>
<html dir="rtl" lang="ar">
<head>
<meta charset="UTF-8">
<title>نتائج تحليل الثغرات الأمنية</title>
<style>
body { font-family: Arial, sans-serif; margin: 20px; }
.vulnerability { border: 1px solid #ccc; margin: 10px 0; padding: 15px; border-radius: 5px; }
.critical { border-color: #ff0000; background-color: #ffe6e6; }
.high { border-color: #ff8800; background-color: #fff0e6; }
.medium { border-color: #ffff00; background-color: #ffffe6; }
.low { border-color: #00ff00; background-color: #e6ffe6; }
.severity { font-weight: bold; }
</style>
</head>
<body>
<h1>نتائج تحليل الثغرات الأمنية</h1>
<p>تم إنشاء التقرير في: ${new Date().toLocaleString('ar')}</p>
`;
results.forEach(result => {
html += `<div class="vulnerability">`;
html += `<h3>التحليل: ${result.id}</h3>`;
html += `<p><strong>درجة المخاطر:</strong> ${result.riskScore}</p>`;
html += `<p><strong>مستوى الثقة:</strong> ${(result.confidence * 100).toFixed(1)}%</p>`;
html += `<p><strong>عدد الثغرات:</strong> ${result.vulnerabilities.length}</p>`;
html += `<p><strong>طرق التحليل:</strong> ${result.methods.join(', ')}</p>`;
if (result.vulnerabilities.length > 0) {
html += '<h4>الثغرات المكتشفة:</h4><ul>';
result.vulnerabilities.forEach(vuln => {
html += `<li>${vuln.type} - الخط ${vuln.line} - الثقة: ${(vuln.confidence * 100).toFixed(1)}%</li>`;
});
html += '</ul>';
}
html += `</div>`;
});
html += '</body></html>';
return html;
}
dispose() {
this.detectionCache.clear();
this.learningData = [];
}
}
/**
* NLP Vulnerability Engine
*/
class NLPVulnerabilityEngine {
async initialize() {
console.log('🧠 Initializing NLP Vulnerability Engine...');
this.vocabulary = this.buildSecurityVocabulary();
}
buildSecurityVocabulary() {
return {
dangerous: ['eval', 'exec', 'system', 'shell_exec', 'passthru', 'popen', 'proc_open'],
sql: ['select', 'insert', 'update', 'delete', 'union', 'drop', 'create', 'alter'],
xss: ['script', 'javascript', 'onclick', 'onload', 'innerHTML', 'document.write'],
injection: ['include', 'require', 'file_get_contents', 'curl_exec', 'wget'],
traversal: ['../', '..\\', '%2e%2e', 'file://', 'dict://']
};
}
async analyze(code) {
const results = [];
const tokens = this.tokenize(code);
for (const [category, words] of Object.entries(this.vocabulary)) {
const matches = this.findContextualMatches(tokens, words, code);
if (matches.length > 0) {
results.push(...matches);
}
}
return results;
}
tokenize(code) {
return code
.toLowerCase()
.replace(/[^\w\s]/g, ' ')
.split(/\s+/)
.filter(token => token.length > 0);
}
findContextualMatches(tokens, dangerousWords, originalCode) {
const results = [];
tokens.forEach((token, index) => {
if (dangerousWords.includes(token)) {
// Check for contextual indicators
const context = this.getContext(tokens, index, 3);
const confidence = this.calculateContextualConfidence(token, context);
if (confidence > 0.6) {
results.push({
type: this.getVulnerabilityType(token),
confidence: confidence,
line: this.getLineNumber(originalCode, token),
column: this.getColumnNumber(originalCode, token),
context: context.join(' '),
method: 'nlp'
});
}
}
});
return results;
}
getContext(tokens, index, windowSize) {
const start = Math.max(0, index - windowSize);
const end = Math.min(tokens.length, index + windowSize + 1);
return tokens.slice(start, end);
}
calculateContextualConfidence(token, context) {
let confidence = 0.5; // Base confidence
// Boost confidence with dangerous context
const dangerousContext = ['input', 'user', 'request', 'get', 'post', 'param'];
const hasDangerousContext = context.some(word => dangerousContext.includes(word));
if (hasDangerousContext) confidence += 0.3;
// Check for assignment patterns
const assignmentPattern = context.some((word, i) =>
word === '=' && i > 0 && dangerousContext.includes(context[i-1])
);
if (assignmentPattern) confidence += 0.2;
return Math.min(0.99, confidence);
}
getVulnerabilityType(token) {
const typeMap = {
'eval': 'code_injection',
'exec': 'command_injection',
'system': 'command_injection',
'shell_exec': 'command_injection',
'select': 'sql_injection',
'union': 'sql_injection',
'script': 'xss',
'javascript': 'xss',
'onclick': 'xss',
'innerHTML': 'xss',
'../': 'path_traversal',
'..\\': 'path_traversal'
};
return typeMap[token] || 'unknown';
}
getLineNumber(code, token) {
const lines = code.split('\n');
for (let i = 0; i < lines.length; i++) {
if (lines[i].includes(token)) {
return i + 1;
}
}
return 1;
}
getColumnNumber(code, token) {
const lines = code.split('\n');
for (let i = 0; i < lines.length; i++) {
const column = lines[i].indexOf(token);
if (column !== -1) {
return column + 1;
}
}
return 1;
}
}
/**
* Advanced Pattern Recognizer
*/
class AdvancedPatternRecognizer {
async initialize() {
console.log('🎯 Initializing Advanced Pattern Recognizer...');
}
async analyze(code, patterns) {
const results = [];
for (const [vulnType, vulnData] of Object.entries(patterns)) {
for (const pattern of vulnData.patterns) {
const matches = [...code.matchAll(new RegExp(pattern.source, pattern.flags))];
matches.forEach(match => {
const confidence = this.calculatePatternConfidence(match, vulnData);
results.push({
type: vulnType,
confidence: confidence,
line: this.getLineFromMatch(code, match),
column: this.getColumnFromMatch(code, match),
match: match[0],
startIndex: match.index,
endIndex: match.index + match[0].length,
severity: vulnData.semantic.severity,
method: 'pattern_recognition'
});
});
}
}
return results;
}
calculatePatternConfidence(match, vulnData) {
let confidence = 0.7; // Base pattern confidence
// Boost confidence based on match context
const matchStr = match[0];
const contextBoost = this.getContextualBoost(matchStr, vulnData.semantic.keywords);
confidence += contextBoost;
return Math.min(0.99, confidence);
}
getContextualBoost(matchStr, keywords) {
let boost = 0;
// Check if match contains security keywords
keywords.forEach(keyword => {
if (matchStr.toLowerCase().includes(keyword)) {
boost += 0.1;
}
});
return Math.min(0.2, boost);
}
getLineFromMatch(code, match) {
const lines = code.substring(0, match.index).split('\n');
return lines.length;
}
getColumnFromMatch(code, match) {
const lines = code.substring(0, match.index).split('\n');
const lastLine = lines[lines.length - 1];
return lastLine.length + 1;
}
}
/**
* ML Vulnerability Classifier
*/
class MLVulnerabilityClassifier {
async initialize() {
console.log('🤖 Initializing ML Vulnerability Classifier...');
// Simulated ML model initialization
this.model = {
weights: new Map(),
bias: 0.1
};
}
async classify(code) {
// Simulated ML classification
const features = this.extractFeatures(code);
const prediction = this.predict(features);
return [{
type: prediction.threatType,
confidence: prediction.confidence,
severity: this.getSeverityScore(prediction.threatType),
method: 'machine_learning',
features: features
}];
}
extractFeatures(code) {
return {
length: code.length,
tokenCount: this.countTokens(code),
complexity: this.calculateComplexity(code),
suspiciousPatterns: this.countSuspiciousPatterns(code),
contextScore: this.calculateContextScore(code)
};
}
countTokens(code) {
return code
.replace(/[^\w]/g, ' ')
.split(/\s+/)
.filter(token => token.length > 0).length;
}
calculateComplexity(code) {
// Cyclomatic complexity approximation
const complexityKeywords = ['if', 'else', 'for', 'while', 'switch', 'case', 'try', 'catch'];
let complexity = 1;
complexityKeywords.forEach(keyword => {
const matches = code.match(new RegExp('\\b' + keyword + '\\b', 'g'));
if (matches) complexity += matches.length;
});
return complexity;
}
countSuspiciousPatterns(code) {
const suspicious = ['eval', 'exec', 'system', 'shell', 'cmd', 'powershell'];
let count = 0;
suspicious.forEach(pattern => {
const matches = code.match(new RegExp('\\b' + pattern + '\\b', 'gi'));
if (matches) count += matches.length;
});
return count;
}
calculateContextScore(code) {
// Score based on security-relevant context
let score = 0;
const contextPatterns = [
/input/i,
/user/i,
/request/i,
/form/i,
/database/i,
/query/i,
/file/i,
/path/i
];
contextPatterns.forEach(pattern => {
if (pattern.test(code)) score += 0.1;
});
return Math.min(1.0, score);
}
predict(features) {
// Simplified ML prediction
const threatScore = (
features.suspiciousPatterns * 0.3 +
features.complexity * 0.2 +
features.contextScore * 0.4 +
(features.length > 1000 ? 0.1 : 0)
);
const threatType = threatScore > 0.7 ? 'high_risk_code' :
threatScore > 0.4 ? 'medium_risk_code' : 'low_risk_code';
return {
threatType: threatType,
confidence: Math.min(0.95, threatScore * 1.2)
};
}
getSeverityScore(threatType) {
const scoreMap = {
'high_risk_code': 8,
'medium_risk_code': 5,
'low_risk_code': 2
};
return scoreMap[threatType] || 3;
}
}
/**
* Semantic Code Analyzer
*/
class SemanticCodeAnalyzer {
async initialize() {
console.log('🔬 Initializing Semantic Code Analyzer...');
}
async analyze(code) {
const results = [];
const semanticPatterns = this.getSemanticPatterns();
for (const [patternName, pattern] of Object.entries(semanticPatterns)) {
const matches = this.findSemanticMatches(code, pattern);
if (matches.length > 0) {
results.push(...matches);
}
}
return results;
}
getSemanticPatterns() {
return {
dangerous_function_calls: {
functions: ['eval', 'exec', 'system', 'shell_exec', 'passthru', 'popen'],
context: ['user', 'input', 'request', 'param'],
severity: 9
},
unsafe_file_operations: {
functions: ['file_get_contents', 'fopen', 'include', 'require'],
context: ['user', 'input', 'path', 'file'],
severity: 8
},
dynamic_code_execution: {
patterns: ['eval\\s*\\(', 'exec\\s*\\(', 'system\\s*\\('],
context: ['variable', 'user', 'request'],
severity: 10
}
};
}
findSemanticMatches(code, pattern) {
const results = [];
// Check for dangerous function calls
if (pattern.functions) {
pattern.functions.forEach(func => {
const regex = new RegExp(`\\b${func}\\s*\\(`, 'gi');
const matches = [...code.matchAll(regex)];
matches.forEach(match => {
const context = this.extractContext(code, match.index, 50);
const contextScore = this.calculateContextRelevance(context, pattern.context);
if (contextScore > 0.6) {
results.push({
type: this.getVulnerabilityType(func),
confidence: contextScore,
line: this.getLineNumber(code, match.index),
column: this.getColumnNumber(code, match.index),
match: match[0],
semantic: true,
severity: pattern.severity,
method: 'semantic_analysis'
});
}
});
});
}
// Check for dynamic patterns
if (pattern.patterns) {
pattern.patterns.forEach(pat => {
const regex = new RegExp(pat, 'gi');
const matches = [...code.matchAll(regex)];
matches.forEach(match => {
const context = this.extractContext(code, match.index, 30);
const contextScore = this.calculateContextRelevance(context, pattern.context);
if (contextScore > 0.7) {
results.push({
type: 'dynamic_code_execution',
confidence: contextScore,
line: this.getLineNumber(code, match.index),
column: this.getColumnNumber(code, match.index),
match: match[0],
semantic: true,
severity: pattern.severity,
method: 'semantic_analysis'
});
}
});
});
}
return results;
}
extractContext(code, index, windowSize) {
const start = Math.max(0, index - windowSize);
const end = Math.min(code.length, index + windowSize);
return code.substring(start, end);
}
calculateContextRelevance(context, keywords) {
let relevance = 0.3; // Base relevance
keywords.forEach(keyword => {
const keywordCount = (context.match(new RegExp(keyword, 'gi')) || []).length;
relevance += keywordCount * 0.2;
});
return Math.min(0.99, relevance);
}
getVulnerabilityType(func) {
const typeMap = {
'eval': 'code_injection',
'exec': 'command_injection',
'system': 'command_injection',
'shell_exec': 'command_injection',
'file_get_contents': 'file_inclusion',
'fopen': 'file_inclusion',
'include': 'file_inclusion',
'require': 'file_inclusion'
};
return typeMap[func] || 'unknown_function';
}
getLineNumber(code, index) {
return code.substring(0, index).split('\n').length;
}
getColumnNumber(code, index) {
const lines = code.substring(0, index).split('\n');
return lines[lines.length - 1].length + 1;
}
}
/**
* Contextual Analyzer
*/
class ContextualAnalyzer {
async initialize() {
console.log('🔍 Initializing Contextual Analyzer...');
}
async analyze(code) {
const results = [];
// Analyze code structure and context
const context = this.analyzeCodeContext(code);
const dataFlow = this.analyzeDataFlow(code);
const controlFlow = this.analyzeControlFlow(code);
// Check for contextual vulnerabilities
if (context.hasUserInput) {
results.push(...this.checkInputValidation(code));
}
if (context.hasDatabaseOperations) {
results.push(...this.checkDatabaseSecurity(code));
}
if (context.hasFileOperations) {
results.push(...this.checkFileSecurity(code));
}
if (context.hasNetworkOperations) {
results.push(...this.checkNetworkSecurity(code));
}
return results;
}
analyzeCodeContext(code) {
return {
hasUserInput: /input|request|get|post|param/i.test(code),
hasDatabaseOperations: /database|query|select|insert|update|delete/i.test(code),
hasFileOperations: /file|read|write|open|include|require/i.test(code),
hasNetworkOperations: /http|https|curl|fetch|ajax/i.test(code),
hasDynamicContent: /eval|exec|system|shell/i.test(code),
complexity: this.calculateCodeComplexity(code)
};
}
calculateCodeComplexity(code) {
let complexity = 0;
const complexityIndicators = [
/if\s*\(/g, /else/g, /for\s*\(/g, /while\s*\(/g,
/switch/g, /case/g, /try/g, /catch/g, /\?\s*[^:]+:/g
];
complexityIndicators.forEach(pattern => {
const matches = code.match(pattern);
if (matches) complexity += matches.length;
});
return complexity;
}
analyzeDataFlow(code) {
// Simplified data flow analysis
return {
sources: this.identifyDataSources(code),
sinks: this.identifyDataSinks(code),
transformations: this.identifyTransformations(code)
};
}
identifyDataSources(code) {
const sources = [];
const sourcePatterns = [
/\$_(?:GET|POST|REQUEST|COOKIE|SERVER)\[/g,
/input\s*\(/g,
/prompt\s*\(/g,
/readline\s*\(/g
];
sourcePatterns.forEach(pattern => {
const matches = code.match(pattern);
if (matches) sources.push(...matches);
});
return sources;
}
identifyDataSinks(code) {
const sinks = [];
const sinkPatterns = [
/innerHTML\s*=/g,
/document\.write\s*\(/g,
/eval\s*\(/g,
/exec\s*\(/g,
/system\s*\(/g,
/file_put_contents\s*\(/g
];
sinkPatterns.forEach(pattern => {
const matches = code.match(pattern);
if (matches) sinks.push(...matches);
});
return sinks;
}
identifyTransformations(code) {
const transformations = [];
const transformPatterns = [
/htmlspecialchars\s*\(/g,
/addslashes\s*\(/g,
/mysql_real_escape_string\s*\(/g,
/json_encode\s*\(/g,
/base64_encode\s*\(/g
];
transformPatterns.forEach(pattern => {
const matches = code.match(pattern);
if (matches) transformations.push(...matches);
});
return transformations;
}
analyzeControlFlow(code) {
// Simplified control flow analysis
return {
hasConditionals: /if\s*\(/.test(code),
hasLoops: /for\s*\(/.test(code) || /while\s*\(/.test(code),
hasExceptions: /try\s*\{/.test(code),
depth: this.calculateNestingDepth(code)
};
}
calculateNestingDepth(code) {
let maxDepth = 0;
let currentDepth = 0;
for (const char of code) {
if (char === '{') {
currentDepth++;
maxDepth = Math.max(maxDepth, currentDepth);
} else if (char === '}') {
currentDepth--;
}
}
return maxDepth;
}
checkInputValidation(code) {
const results = [];
// Check if user input is used without validation
if (/\$_(?:GET|POST|REQUEST)/.test(code) && !/filter_var|htmlspecialchars|addslashes/.test(code)) {
results.push({
type: 'missing_input_validation',
confidence: 0.8,
severity: 7,
method: 'contextual_analysis',
message: 'User input used without proper validation'
});
}
return results;
}
checkDatabaseSecurity(code) {
const results = [];
// Check for SQL injection patterns
if (/\$_(?:GET|POST|REQUEST)/.test(code) && /query|select|insert|update|delete/i.test(code)) {
if (!/prepare|parameterized|bind_param/.test(code)) {
results.push({
type: 'potential_sql_injection',
confidence: 0.7,
severity: 9,
method: 'contextual_analysis',
message: 'Potential SQL injection vulnerability detected'
});
}
}
return results;
}
checkFileSecurity(code) {
const results = [];
// Check for file inclusion with user input
if (/\$_(?:GET|POST|REQUEST)/.test(code) && /(include|require)(_once)?\s*\(/i.test(code)) {
results.push({
type: 'file_inclusion_vulnerability',
confidence: 0.8,
severity: 8,
method: 'contextual_analysis',
message: 'File inclusion with user input detected'
});
}
return results;
}
checkNetworkSecurity(code) {
const results = [];
// Check for insecure HTTP requests
if (/http:\/\//.test(code) && !/https:\/\//.test(code)) {
results.push({
type: 'insecure_http_request',
confidence: 0.9,
severity: 6,
method: 'contextual_analysis',
message: 'Insecure HTTP request detected (should use HTTPS)'
});
}
return results;
}
}
// Export for use in other modules
if (typeof module !== 'undefined' && module.exports) {
module.exports = {
AdvancedVulnerabilityDetector,
NLPVulnerabilityEngine,
AdvancedPatternRecognizer,
MLVulnerabilityClassifier,
SemanticCodeAnalyzer,
ContextualAnalyzer
};
}