| |
| |
|
|
| function renderResultsView() { |
| const results = window.SCAFU?.scanResults || []; |
| const critical = results.filter(r => r.severity === 'critical'); |
| const high = results.filter(r => r.severity === 'high'); |
| const medium = results.filter(r => r.severity === 'medium'); |
| const low = results.filter(r => r.severity === 'low'); |
|
|
| return ` |
| <div class="border-b border-white/10 p-6"> |
| <div class="flex items-center justify-between mb-4"> |
| <div> |
| <h1 class="text-2xl font-bold mb-1">Scan Results</h1> |
| <p class="text-sm text-slate-400">Detailed vulnerability findings from latest scan</p> |
| </div> |
| <div class="flex items-center gap-2"> |
| <button class="px-4 py-2 rounded-lg border border-white/20 text-slate-400 hover:bg-white/5 text-sm font-medium"> |
| <svg class="w-4 h-4 inline mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 4a1 1 0 011-1h16a1 1 0 011 1v2.586a1 1 0 01-.293.707l-6.414 6.414a1 1 0 00-.293.707V17l-4 4v-6.586a1 1 0 00-.293-.707L3.293 7.293A1 1 0 013 6.586V4z"></path></svg> |
| Filter |
| </button> |
| <button onclick="exportReport()" class="px-4 py-2 rounded-lg bg-emerald-500 text-slate-950 hover:bg-emerald-600 text-sm font-semibold"> |
| Export Report |
| </button> |
| </div> |
| </div> |
| |
| <!-- Stats Bar --> |
| <div class="grid grid-cols-4 gap-4"> |
| <div class="rounded-lg border border-red-400/30 bg-red-500/10 p-3"> |
| <div class="text-xs text-slate-500 uppercase tracking-wider mb-1">Critical</div> |
| <div class="text-2xl font-bold text-red-400 font-mono">${critical.length}</div> |
| </div> |
| <div class="rounded-lg border border-orange-400/30 bg-orange-500/10 p-3"> |
| <div class="text-xs text-slate-500 uppercase tracking-wider mb-1">High</div> |
| <div class="text-2xl font-bold text-orange-400 font-mono">${high.length}</div> |
| </div> |
| <div class="rounded-lg border border-yellow-400/30 bg-yellow-500/10 p-3"> |
| <div class="text-xs text-slate-500 uppercase tracking-wider mb-1">Medium</div> |
| <div class="text-2xl font-bold text-yellow-400 font-mono">${medium.length}</div> |
| </div> |
| <div class="rounded-lg border border-white/10 bg-white/5 p-3"> |
| <div class="text-xs text-slate-500 uppercase tracking-wider mb-1">Total</div> |
| <div class="text-2xl font-bold text-white font-mono">${results.length}</div> |
| </div> |
| </div> |
| </div> |
| |
| <div class="flex-1 overflow-y-auto p-6"> |
| ${results.length === 0 ? ` |
| <div class="flex flex-col items-center justify-center h-full text-center"> |
| <svg class="w-24 h-24 text-slate-600 mb-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z"></path></svg> |
| <h3 class="text-xl font-bold text-slate-400 mb-2">No Results Yet</h3> |
| <p class="text-sm text-slate-500 mb-4">Run a scan to see vulnerability findings here</p> |
| <button onclick="switchTab('scanners')" class="px-6 py-2 rounded-lg bg-emerald-500 text-slate-950 hover:bg-emerald-600 font-semibold"> |
| Start Scan |
| </button> |
| </div> |
| ` : ` |
| <div class="space-y-4"> |
| ${results.map(vuln => renderVulnerabilityCard(vuln)).join('')} |
| </div> |
| `} |
| </div> |
| `; |
| } |
|
|
| function renderVulnerabilityCard(vuln) { |
| const severityColors = { |
| critical: { bg: 'bg-red-500/10', border: 'border-red-400/30', text: 'text-red-400', badge: 'bg-red-500/20' }, |
| high: { bg: 'bg-orange-500/10', border: 'border-orange-400/30', text: 'text-orange-400', badge: 'bg-orange-500/20' }, |
| medium: { bg: 'bg-yellow-500/10', border: 'border-yellow-400/30', text: 'text-yellow-400', badge: 'bg-yellow-500/20' }, |
| low: { bg: 'bg-blue-500/10', border: 'border-blue-400/30', text: 'text-blue-400', badge: 'bg-blue-500/20' } |
| }; |
| const colors = severityColors[vuln.severity] || severityColors.medium; |
|
|
| return ` |
| <div class="rounded-xl border ${colors.border} ${colors.bg} p-6 cursor-pointer hover:border-opacity-60 transition-all" onclick='showVulnerabilityDetail(${JSON.stringify(vuln)})'> |
| <div class="flex items-start justify-between mb-4"> |
| <div class="flex-1"> |
| <div class="flex items-center gap-3 mb-2"> |
| <span class="px-3 py-1 rounded text-xs font-bold uppercase ${colors.badge} ${colors.text} border ${colors.border}">${vuln.severity}</span> |
| <span class="px-3 py-1 rounded bg-white/5 text-slate-400 text-xs font-mono">CVSS ${vuln.cvss}</span> |
| <span class="px-3 py-1 rounded bg-white/5 text-slate-400 text-xs font-mono">${vuln.cwe}</span> |
| </div> |
| <h3 class="text-lg font-bold text-white mb-2">${vuln.title}</h3> |
| <p class="text-sm text-slate-300 mb-3">${vuln.description}</p> |
| <div class="flex items-center gap-4 text-xs text-slate-400"> |
| <span class="flex items-center gap-1"> |
| <svg class="w-3 h-3" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"></path></svg> |
| ${vuln.scanner} |
| </span> |
| <span>•</span> |
| <span class="font-mono">${vuln.url}</span> |
| </div> |
| </div> |
| <button class="p-2 rounded-lg hover:bg-white/5 flex-shrink-0"> |
| <svg class="w-5 h-5 text-slate-400" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7"></path></svg> |
| </button> |
| </div> |
| |
| <div class="grid grid-cols-2 gap-4 pt-4 border-t border-white/10"> |
| <div> |
| <div class="text-xs text-slate-500 mb-1">Impact</div> |
| <div class="text-sm text-slate-300">${vuln.impact.substring(0, 80)}${vuln.impact.length > 80 ? '...' : ''}</div> |
| </div> |
| <div> |
| <div class="text-xs text-slate-500 mb-1">Remediation</div> |
| <div class="text-sm text-slate-300">${vuln.remediation.substring(0, 80)}${vuln.remediation.length > 80 ? '...' : ''}</div> |
| </div> |
| </div> |
| </div> |
| `; |
| } |
|
|
| function showVulnerabilityDetail(vuln) { |
| const severityColors = { |
| critical: { bg: 'bg-red-500/10', border: 'border-red-400/30', text: 'text-red-400' }, |
| high: { bg: 'bg-orange-500/10', border: 'border-orange-400/30', text: 'text-orange-400' }, |
| medium: { bg: 'bg-yellow-500/10', border: 'border-yellow-400/30', text: 'text-yellow-400' }, |
| low: { bg: 'bg-blue-500/10', border: 'border-blue-400/30', text: 'text-blue-400' } |
| }; |
| const colors = severityColors[vuln.severity] || severityColors.medium; |
|
|
| showModal(vuln.title, ` |
| <div class="space-y-4"> |
| <div class="flex items-center justify-between"> |
| <div class="flex items-center gap-3"> |
| <span class="px-3 py-1 rounded text-xs font-bold uppercase ${colors.bg} ${colors.text} border ${colors.border}">${vuln.severity}</span> |
| <span class="px-3 py-1 rounded bg-white/5 text-slate-400 text-xs font-mono">CVSS ${vuln.cvss}</span> |
| <span class="px-3 py-1 rounded bg-white/5 text-slate-400 text-xs font-mono">${vuln.cwe}</span> |
| </div> |
| <span class="text-xs text-slate-500">Found by ${vuln.scanner}</span> |
| </div> |
| |
| <div class="${colors.bg} border ${colors.border} rounded-lg p-4"> |
| <div class="text-sm font-semibold ${colors.text} mb-2">⚠️ Exploitable Vulnerability</div> |
| <div class="text-sm text-slate-300">${vuln.description}</div> |
| </div> |
| |
| <div> |
| <div class="text-sm font-semibold text-slate-300 mb-2">Location</div> |
| <div class="bg-slate-800 rounded-lg p-3 font-mono text-xs text-slate-300"> |
| ${vuln.url} |
| </div> |
| </div> |
| |
| <div> |
| <div class="text-sm font-semibold text-slate-300 mb-2">Impact</div> |
| <div class="text-sm text-slate-400">${vuln.impact}</div> |
| </div> |
| |
| <div> |
| <div class="text-sm font-semibold text-slate-300 mb-2">Proof of Concept</div> |
| <div class="bg-slate-950 rounded-lg p-4 font-mono text-xs text-emerald-400 overflow-x-auto"> |
| <pre>${vuln.exploitCode}</pre> |
| </div> |
| </div> |
| |
| <div> |
| <div class="text-sm font-semibold text-slate-300 mb-2">Remediation</div> |
| <div class="text-sm text-slate-400">${vuln.remediation}</div> |
| </div> |
| |
| <div class="flex gap-3"> |
| <button class="flex-1 px-4 py-2 rounded-lg border border-emerald-400/30 text-emerald-400 hover:bg-emerald-500/10"> |
| Copy Proof of Concept |
| </button> |
| <button class="flex-1 px-4 py-2 rounded-lg bg-emerald-500 text-slate-950 hover:bg-emerald-600"> |
| Export Finding |
| </button> |
| </div> |
| </div> |
| `); |
| } |
|
|
| |
| |
|
|