File size: 4,038 Bytes
f4ff0e8
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
"""

Visualization functions for security analysis results

"""
import plotly.express as px
import plotly.graph_objects as go
from typing import List
from models import SecurityVulnerability

def create_severity_chart(vulnerabilities: List[SecurityVulnerability]):
    """Create severity distribution chart"""
    severity_counts = {}
    for vuln in vulnerabilities:
        severity_counts[vuln.severity] = severity_counts.get(vuln.severity, 0) + 1
    
    colors = {
        'critical': '#e74c3c',
        'high': '#e67e22',
        'medium': '#f39c12',
        'low': '#f1c40f'
    }
    
    fig = px.pie(
        values=list(severity_counts.values()),
        names=list(severity_counts.keys()),
        title="Security Issues by Severity",
        color=list(severity_counts.keys()),
        color_discrete_map=colors
    )
    
    fig.update_traces(textposition='inside', textinfo='percent+label')
    fig.update_layout(showlegend=True, height=400)
    
    return fig

def create_category_chart(vulnerabilities: List[SecurityVulnerability]):
    """Create category distribution chart"""
    category_counts = {}
    for vuln in vulnerabilities:
        category_counts[vuln.category] = category_counts.get(vuln.category, 0) + 1
    
    fig = px.bar(
        x=list(category_counts.keys()),
        y=list(category_counts.values()),
        title="Security Issues by Category",
        color=list(category_counts.values()),
        color_continuous_scale="Reds"
    )
    
    fig.update_layout(
        xaxis_title="Security Categories",
        yaxis_title="Number of Issues",
        showlegend=False,
        height=400
    )
    
    return fig

def create_cvss_distribution(vulnerabilities: List[SecurityVulnerability]):
    """Create CVSS score distribution"""
    cvss_scores = [vuln.cvss_score for vuln in vulnerabilities if vuln.cvss_score]
    
    if not cvss_scores:
        return None
    
    fig = px.histogram(
        x=cvss_scores,
        nbins=10,
        title="CVSS Score Distribution",
        color_discrete_sequence=['#3498db']
    )
    
    fig.update_layout(
        xaxis_title="CVSS Score",
        yaxis_title="Number of Vulnerabilities",
        height=400
    )
    
    return fig

def create_severity_timeline(vulnerabilities: List[SecurityVulnerability]):
    """Create a timeline view of vulnerabilities by line number"""
    if not vulnerabilities:
        return None
    
    # Group vulnerabilities by severity
    severity_data = {'critical': [], 'high': [], 'medium': [], 'low': []}
    
    for vuln in vulnerabilities:
        if vuln.line_number:
            severity_data[vuln.severity].append({
                'line': vuln.line_number,
                'title': vuln.title,
                'rule_id': vuln.rule_id
            })
    
    fig = go.Figure()
    
    colors = {
        'critical': '#e74c3c',
        'high': '#e67e22',
        'medium': '#f39c12',
        'low': '#f1c40f'
    }
    
    for severity, items in severity_data.items():
        if items:
            lines = [item['line'] for item in items]
            titles = [f"{item['rule_id']}: {item['title']}" for item in items]
            
            fig.add_trace(go.Scatter(
                x=lines,
                y=[severity] * len(lines),
                mode='markers+text',
                name=severity.title(),
                text=titles,
                textposition="top center",
                marker=dict(
                    color=colors[severity],
                    size=12,
                    symbol='diamond'
                ),
                hovertemplate='<b>%{text}</b><br>Line: %{x}<br>Severity: %{y}<extra></extra>'
            ))
    
    fig.update_layout(
        title="Vulnerabilities by Code Location",
        xaxis_title="Line Number",
        yaxis_title="Severity",
        height=400,
        showlegend=True
    )
    
    return fig