-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdashboard.py
181 lines (152 loc) · 7.89 KB
/
dashboard.py
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
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
import json
import streamlit as st
import plotly.express as px
import os
from glob import glob
# Função para pegar o último arquivo JSON criado
def get_latest_json_file(directory="."):
json_files = glob(os.path.join(directory, "*.json"))
if not json_files:
return None
latest_file = max(json_files, key=os.path.getctime) # Ordena pelo tempo de criação
return latest_file
# Função para calcular a criticidade com base nos CVEs (usando pontuação CVSS)
def calculate_risk_index(cve_list):
risk_score = 0
cvss_scores = {
"CVE-2020-11022": 7.5, # Alta criticidade
"CVE-2019-11358": 6.0, # Média criticidade
"CVE-2020-7598": 5.5 # Média criticidade
}
for cve in cve_list:
risk_score += cvss_scores.get(cve, 0) # Se CVE não estiver no dicionário, assume-se 0
return risk_score / len(cve_list) if cve_list else 0
# Função para classificar criticidade (baixa, média, alta) com base na pontuação CVSS
def classify_severity(cve):
cvss_scores = {
"CVE-2020-11022": 7.5, # Alta criticidade
"CVE-2019-11358": 6.0, # Média criticidade
"CVE-2020-7598": 5.5 # Média criticidade
}
score = cvss_scores.get(cve, 0)
if score >= 7.0:
return "Alta"
elif score >= 4.0:
return "Média"
else:
return "Baixa"
# Função para gerar recomendações baseadas no CVE
def get_recommendations(cve):
recommendations = {
"CVE-2020-11022": "Vulnerabilidade de XSS no jQuery. Atualize para a versão mais recente do jQuery. Veja detalhes <a href='https://nvd.nist.gov/vuln/detail/CVE-2020-11022' target='_blank'>aqui</a>.",
"CVE-2019-11358": "Vulnerabilidade de XSS no jQuery. Recomenda-se atualizar o jQuery para uma versão segura. Veja detalhes <a href='https://nvd.nist.gov/vuln/detail/CVE-2019-11358' target='_blank'>aqui</a>.",
"CVE-2020-7598": "Vulnerabilidade de XSS através de eventos em imagens (ex.: onerror). Evite usar diretamente atributos inseguros. Veja detalhes <a href='https://nvd.nist.gov/vuln/detail/CVE-2020-7598' target='_blank'>aqui</a>."
}
return recommendations.get(cve, "Recomendação não disponível para este CVE.")
# Título do dashboard
st.title("Dashboard de Segurança XSS")
# Procurar automaticamente o último arquivo JSON gerado
latest_json_file = get_latest_json_file()
if latest_json_file:
st.write(f"Carregando o arquivo mais recente: {latest_json_file}")
try:
# Carregar o arquivo JSON mais recente
with open(latest_json_file) as f:
data = json.load(f)
# Cabeçalho estruturado em formato de tabela
st.header("Resumo Geral")
# Contar vulnerabilidades críticas com base nos CVEs
critical_vulns = [result for result in data['detalhes_resultados'] if result['cve'] is not None]
# Calcular índice de risco baseado no CVSS
cve_list = [result["cve"] for result in data["detalhes_resultados"]]
risk_index = calculate_risk_index(cve_list)
# Contadores de métodos HTTP
method_counts = {"GET": 0, "POST": 0, "OUTROS": 0}
# Coletar dados de métodos
for result in data['detalhes_resultados']:
method = result.get('method', 'OUTROS').upper()
if method in method_counts:
method_counts[method] += 1
else:
method_counts['OUTROS'] += 1
# Organizando os dados em uma tabela
table_data = {
"Resumo Geral": ["URL Analisada", "Total de Formulários Analisados", "Total de Vulnerabilidades",
"Vulnerabilidades Críticas", "Índice de Risco Geral", "Métodos HTTP"],
"Valor": [
data['url_analisada'],
len(data['detalhes_resultados']),
len(critical_vulns),
f"Alta: {len([v for v in critical_vulns if classify_severity(v['cve']) == 'Alta'])}, "
f"Média: {len([v for v in critical_vulns if classify_severity(v['cve']) == 'Média'])}, "
f"Baixa: {len([v for v in critical_vulns if classify_severity(v['cve']) == 'Baixa'])}",
f"{risk_index:.1f}/10",
f"GET: {method_counts['GET']}, POST: {method_counts['POST']}, Outros: {method_counts['OUTROS']}"
]
}
# Exibir a tabela formatada
st.table(table_data)
# Insights Gráficos
st.header("Insights Gráficos")
# Gráfico de Proporção de Payloads Refletidos
reflected_payloads = [res['reflected_payload'] for res in data['detalhes_resultados']]
fig_reflected = px.pie(
names=["Refletido", "Não Refletido"],
values=[reflected_payloads.count(True), reflected_payloads.count(False)],
title="Proporção de Payloads Refletidos",
color_discrete_sequence=["#3498DB", "#BDC3C7"] # Azul para refletido, cinza para não refletido
)
st.plotly_chart(fig_reflected, use_container_width=True)
# Gráfico de Vulnerabilidades por Criticidade
severity_counts = {"Alta": 0, "Média": 0, "Baixa": 0}
for result in data['detalhes_resultados']:
severity = classify_severity(result['cve'])
severity_counts[severity] += 1
fig_severity = px.bar(
x=list(severity_counts.keys()), # Alta, Média, Baixa
y=list(severity_counts.values()), # Contagem de vulnerabilidades
title="Distribuição de Vulnerabilidades por Criticidade",
color=list(severity_counts.keys()),
color_discrete_map={"Alta": "#E74C3C", "Média": "#F39C12", "Baixa": "#F1C40F"} # Vermelho, Laranja, Amarelo
)
st.plotly_chart(fig_severity, use_container_width=True)
# Detalhamento Técnico e Recomendações
st.header("Detalhamento Técnico e Recomendações")
# Ordenar os resultados pela criticidade (Alta -> Média -> Baixa)
severity_order = {"Alta": 0, "Média": 1, "Baixa": 2}
sorted_results = sorted(data['detalhes_resultados'], key=lambda res: severity_order[classify_severity(res['cve'])])
# Mapeamento de cores para as bolinhas
color_map = {"Alta": "#E74C3C", "Média": "#F39C12", "Baixa": "#F1C40F"}
for idx, result in enumerate(sorted_results, 1):
# Obter a criticidade do item
criticidade = classify_severity(result['cve'])
# Bolinha colorida indicando a criticidade
bolinha_html = f"<span style='color:{color_map[criticidade]};font-size:20px;'>●</span>"
# Adicionar a criticidade ao título do item
st.markdown(
f"""
{bolinha_html} **Item #{idx} [{criticidade}] - {result['scan_type']}**
""",
unsafe_allow_html=True
)
st.write(f"**Payload:** {result['payload']}") # Payload como texto
st.write(f"**Status HTTP:** {result['status_code']}")
st.write(f"**Payload Refletido:** {'Sim' if result['reflected_payload'] else 'Não'}")
st.write(f"**CVE:** {result['cve']}")
st.write(f"**Descrição:** {result['description']}")
st.write(f"**OWASP Categoria:** {result.get('owasp_category', 'Categoria OWASP não disponível')}")
# Adicionar recomendações com base no CVE
st.markdown(
f"""
<div style='background-color:#2c3e50;padding:10px;border-radius:5px;color:#ecf0f1;'>
🔴 {get_recommendations(result['cve'])}
</div>
""",
unsafe_allow_html=True
)
# Adicionar uma linha para separar os itens
st.markdown("---")
except FileNotFoundError:
st.error(f"Arquivo {latest_json_file} não encontrado. Por favor, verifique o nome e tente novamente.")
else:
st.error("Nenhum arquivo JSON encontrado no diretório.")