From 4d480a4b4a20a20cca5cd437888d3bdfa4628237 Mon Sep 17 00:00:00 2001 From: Flatlogic Bot Date: Mon, 1 Dec 2025 11:05:34 +0000 Subject: [PATCH] Auto commit: 2025-12-01T11:05:34.155Z --- api/detect-type.php | 60 ++++++++++ assets/css/custom.css | 121 +++++++++++++++++++++ assets/js/main.js | 159 +++++++++++++++++++++++++++ index.php | 248 ++++++++++++++++++------------------------ 4 files changed, 443 insertions(+), 145 deletions(-) create mode 100644 api/detect-type.php create mode 100644 assets/css/custom.css create mode 100644 assets/js/main.js diff --git a/api/detect-type.php b/api/detect-type.php new file mode 100644 index 0000000..a6cf717 --- /dev/null +++ b/api/detect-type.php @@ -0,0 +1,60 @@ + 'No input provided.']); + exit; +} + +// Simple detection for URL +if (filter_var($input, FILTER_VALIDATE_URL)) { + $detected_language = 'URL'; + $suggestion = 'Check for common web vulnerabilities'; +} else { + $ai_prompt = "Classify the following code snippet and return only the language name (e.g., 'JavaScript', 'Python', 'SQL', 'PHP', 'HTML'). If it's not a recognizable language, return 'Text'. Snippet: + +" . $input; + + $resp = LocalAIApi::createResponse([ + 'input' => [ ['role' => 'system', 'content' => 'You are a code classification assistant.'], + ['role' => 'user', 'content' => $ai_prompt], + ], + ]); + + $detected_language = 'Text'; // Default + if (!empty($resp['success'])) { + $text = LocalAIApi::extractText($resp); + if (!empty($text)) { + $detected_language = trim($text); + } + } + + $suggestion = 'Check for common vulnerabilities in ' . $detected_language; + switch ($detected_language) { + case 'JavaScript': + $suggestion = 'Check for XSS (Cross-Site Scripting) vulnerabilities'; + break; + case 'SQL': + $suggestion = 'Check for SQL Injection vulnerabilities'; + break; + case 'PHP': + $suggestion = 'Check for file inclusion and remote code execution risks'; + break; + case 'HTML': + $suggestion = 'Check for broken HTML structure and insecure forms'; + break; + } +} + +echo json_encode([ + 'language' => $detected_language, + 'suggestion' => $suggestion, +]); diff --git a/assets/css/custom.css b/assets/css/custom.css new file mode 100644 index 0000000..5b6abfe --- /dev/null +++ b/assets/css/custom.css @@ -0,0 +1,121 @@ + +@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap'); + +:root { + --primary-color: #0d9488; + --primary-hover: #14b8a6; + --secondary-color: #f97316; + --bg-color: #f8fafc; + --surface-color: #ffffff; + --text-dark: #1e293b; + --text-light: #475569; + --border-color: #e2e8f0; + --radius-md: 0.5rem; + --radius-sm: 0.375rem; + --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.05); + --shadow-md: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1); +} + +body { + background-color: var(--bg-color); + font-family: 'Inter', sans-serif; + color: var(--text-light); +} + +.navbar-brand { + font-weight: 700; + color: var(--text-dark); +} + +.scan-section { + background-color: var(--surface-color); + border-radius: var(--radius-md); + box-shadow: var(--shadow-md); + padding: 2rem; +} + +.form-control, .form-select { + border-radius: var(--radius-sm); + border-color: var(--border-color); +} +.form-control:focus { + border-color: var(--primary-color); + box-shadow: 0 0 0 0.25rem rgba(13, 148, 136, 0.25); +} + +.btn-primary { + background-color: var(--primary-color); + border-color: var(--primary-color); + border-radius: var(--radius-sm); + padding: 0.75rem 1.5rem; + font-weight: 600; +} + +.btn-primary:hover, .btn-primary:focus { + background-color: var(--primary-hover); + border-color: var(--primary-hover); +} + +.btn-primary:disabled { + background-color: #94a3b8; + border-color: #94a3b8; +} + +.results-section { + display: none; +} + +.risk-meter { + width: 150px; + height: 150px; +} + +.badge-severity { + font-size: 0.8rem; + font-weight: 600; + padding: 0.4em 0.8em; + border-radius: var(--radius-sm); +} + +.badge-critical { background-color: #ef4444; color: white; } +.badge-high { background-color: #f97316; color: white; } +.badge-medium { background-color: #facc15; color: var(--text-dark); } +.badge-low { background-color: #22c55e; color: white; } + +.issue-card { + border: 1px solid var(--border-color); + border-radius: var(--radius-md); + box-shadow: var(--shadow-sm); + margin-bottom: 1rem; +} + +.issue-card .card-body { + padding: 1.5rem; +} + +.issue-card h5 { + color: var(--text-dark); + font-weight: 600; +} + +.fix-code { + background-color: #f1f5f9; + border: 1px solid var(--border-color); + border-radius: var(--radius-sm); + padding: 1rem; + font-family: monospace; + white-space: pre-wrap; + word-break: break-all; +} + +#loader { + display: none; +} + +/* Spinner animation */ +.spinner-border { + width: 3rem; + height: 3rem; + color: var(--primary-color); +} + diff --git a/assets/js/main.js b/assets/js/main.js new file mode 100644 index 0000000..d717a9c --- /dev/null +++ b/assets/js/main.js @@ -0,0 +1,159 @@ +document.addEventListener('DOMContentLoaded', function () { + constcodeInput = document.getElementById('codeInput'); + const promptInput = document.getElementById('promptInput'); + const scanButton = document.getElementById('scanButton'); + const scanForm = document.getElementById('scanForm'); + const loader = document.getElementById('loader'); + const resultsSection = document.getElementById('resultsSection'); + const riskScoreValue = document.getElementById('riskScoreValue'); + const riskScoreChart = document.getElementById('riskScoreChart'); + const issuesContainer = document.getElementById('issuesContainer'); + + const detectionResult = document.getElementById('detectionResult'); + const detectedLanguage = document.getElementById('detectedLanguage'); + const detectionSuggestion = document.getElementById('detectionSuggestion'); + + function debounce(func, delay) { + let timeout; + return function(...args) { + clearTimeout(timeout); + timeout = setTimeout(() => func.apply(this, args), delay); + }; + } + + const handleCodeInputChange = debounce(async () => { + const code = codeInput.value.trim(); + if (code.length < 10) { // Don't run for very short inputs + detectionResult.style.display = 'none'; + return; + } + + try { + const response = await fetch('/api/detect-type.php', { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ code: code }) + }); + + if (response.ok) { + const data = await response.json(); + if (data.language && data.language !== 'Text') { + detectedLanguage.textContent = data.language; + detectionSuggestion.textContent = data.suggestion; + detectionResult.style.display = 'block'; + } else { + detectionResult.style.display = 'none'; + } + } + } catch (error) { + console.error('Error detecting language:', error); + detectionResult.style.display = 'none'; + } + }, 500); // 500ms delay + + codeInput.addEventListener('input', handleCodeInputChange); + + function validateInputs() { + const code = codeInput.value.trim(); + const prompt = promptInput.value.trim(); + scanButton.disabled = !(code && prompt); + } + + codeInput.addEventListener('input', validateInputs); + promptInput.addEventListener('input', validateInputs); + + scanForm.addEventListener('submit', function (e) { + e.preventDefault(); + + document.querySelector('.scan-section').style.display = 'none'; + loader.style.display = 'block'; + + // Simulate API call + setTimeout(() => { + loader.style.display = 'none'; + displayMockResults(); + }, 3000); + }); + + function displayMockResults() { + const mockData = { + "risk_score": 78, + "issues": [ + { + "type": "SQL Injection", + "severity": "Critical", + "location": "Login form, 'username' parameter", + "explanation": "Your script appears to be vulnerable to SQL Injection because it doesn't properly sanitize user input before including it in a database query.", + "fix": "Use prepared statements and parameterized queries. Example in PHP: $stmt = $pdo->prepare('SELECT * FROM users WHERE username = ?'); $stmt->execute([$username]);" + }, + { + "type": "Cross-Site Scripting (XSS)", + "severity": "High", + "location": "Search results page", + "explanation": "The search term is reflected back to the page without being sanitized, allowing an attacker to inject malicious scripts.", + "fix": "Always escape HTML output. In PHP, use: echo htmlspecialchars($searchTerm, ENT_QUOTES, 'UTF-8');" + }, + { + "type": "Weak Password Policy", + "severity": "Medium", + "location": "User registration script", + "explanation": "The script does not enforce a strong password policy, making user accounts susceptible to brute-force attacks.", + "fix": "Require passwords to be at least 12 characters long and include a mix of uppercase, lowercase, numbers, and symbols." + } + ] + }; + + riskScoreValue.textContent = mockData.risk_score; + updateRiskChart(mockData.risk_score); + + issuesContainer.innerHTML = ''; + mockData.issues.forEach(issue => { + const severityClass = `badge-${issue.severity.toLowerCase()}`; + const issueHtml = ` +
+
+
+
${issue.type}
+ ${issue.severity} +
+
Location: ${issue.location}
+

${issue.explanation}

+
Suggested Fix:
+
${issue.fix}
+
+
+ `; + issuesContainer.insertAdjacentHTML('beforeend', issueHtml); + }); + + resultsSection.style.display = 'block'; + } + + function updateRiskChart(score) { + const chart = new Chart(riskScoreChart, { + type: 'doughnut', + data: { + datasets: [{ + data: [score, 100 - score], + backgroundColor: [getScoreColor(score), '#e2e8f0'], + borderWidth: 0, + }] + }, + options: { + cutout: '70%', + plugins: { + tooltip: { enabled: false }, + legend: { display: false } + } + } + }); + } + + function getScoreColor(score) { + if (score > 75) return '#ef4444'; // Critical + if (score > 50) return '#f97316'; // High + if (score > 25) return '#facc15'; // Medium + return '#22c55e'; // Low + } + +}); diff --git a/index.php b/index.php index 7205f3d..b9c3a8a 100644 --- a/index.php +++ b/index.php @@ -1,150 +1,108 @@ - - + - - - New Style - - - - - - - - - - - - - - - - - - - + + + SecureScan - AI-Powered Vulnerability Scanner + + + + + + + + + + + + + -
-
-

Analyzing your requirements and generating your website…

-
- Loading… -
-

AI is collecting your requirements and applying the first changes.

-

This page will update automatically as the plan is implemented.

-

Runtime: PHP — UTC

-
-
- + + + +
+
+
+

Scan for Vulnerabilities

+

Instantly analyze a URL or code snippet with AI.

+
+
+
+ + + +
+
+ + +
+
+ +
+
+
+ +
+
+ Loading... +
+

Analyzing... this may take a moment.

+
+ +
+
+

Scan Report

+
+ +
+
+
+
+ +
+ -- +
Score
+
+
+
+
+

Overall Risk Score

+

This score represents the estimated security risk based on the vulnerabilities found. A higher score indicates a greater risk that should be addressed immediately.

+
+
+
+ +

Found Issues

+
+ +
+
+
+ + + + + + + + + - + \ No newline at end of file