-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathscript.py
More file actions
178 lines (150 loc) · 7.2 KB
/
script.py
File metadata and controls
178 lines (150 loc) · 7.2 KB
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
import os
import sys
import json
from datetime import datetime
# Importa as classes que criamos
from config import Configuracao
from analyzers.detector import DetectorVulnerabilidade
from analyzers.vulnerability import Vulnerabilidade
from report_generator import GeradorRelatorio
# Função para coletar arquivos PHP de um caminho (arquivo ou diretório)
def collect_php_files_from_path(path: str) -> list[str]:
php_files = []
if os.path.isfile(path) and path.lower().endswith('.php'):
# Se o caminho for um arquivo PHP, adiciona ele mesmo
php_files.append(path)
elif os.path.isdir(path):
# Se o caminho for um diretório, percorre ele e adiciona todos os arquivos PHP
for root, _, files in os.walk(path):
for file in files:
if file.lower().endswith('.php'):
php_files.append(os.path.join(root, file))
return php_files
class AnalisadorEstatico:
"""
Orquestra o processo de análise estática de código PHP,
detectando vulnerabilidades e gerando relatórios.
"""
def __init__(self, vul_config_path: str, diretorio_saida: str = "report"):
self.configuracao = Configuracao(vul_config_path)
self.detector = DetectorVulnerabilidade(self.configuracao)
self.relatorio = GeradorRelatorio (diretorio_saida)
self.diretorio_saida = diretorio_saida
def analisar_arquivo_php(self, file_path: str, quiet: bool = False):
"""
Analisa um único arquivo PHP em busca de vulnerabilidades.
Se quiet for True, suprime a saída no console.
"""
if not os.path.exists(file_path):
if not quiet:
print(f"Erro: Arquivo '{file_path}' não encontrado.", file=sys.stderr)
return
if not quiet:
print(f"Iniciando análise de: {file_path}")
try:
with open(file_path, 'r', encoding='utf-8') as file:
php_code = file.read()
except Exception as e:
if not quiet:
print(f"Erro ao ler o arquivo '{file_path}': {e}", file=sys.stderr)
return
vulnerabilidades_encontradas = self.detector.analyze_php_code(php_code, file_path)
if vulnerabilidades_encontradas:
if not quiet:
print(f"Vulnerabilidades encontradas em {file_path}:")
for vul in vulnerabilidades_encontradas:
self.relatorio.adicionar_vulnerabilidade(vul)
if not quiet:
print(f"- {vul.type} na linha {vul.line} do arquivo: {os.path.basename(vul.file_path)} (Severidade: {vul.severity})")
elif not quiet:
print(f"Nenhuma vulnerabilidade encontrada em {file_path}.")
def analisar_multiplos_arquivos_php(self, file_paths: list, generate_reports: bool = True, output_format: str = "text") -> list:
"""
Analisa uma lista de arquivos PHP em busca de vulnerabilidades.
Se generate_reports for True, gera os relatórios HTML/PDF.
Retorna a lista de todas as vulnerabilidades encontradas.
"""
self.relatorio.vulnerabilities = []
quiet_mode = output_format == "json"
if not file_paths:
if not quiet_mode:
print("Nenhum arquivo para analisar. Abortando.")
return []
for file_path in file_paths:
self.analisar_arquivo_php(file_path, quiet=quiet_mode)
if not quiet_mode:
if generate_reports and self.relatorio.get_vulnerabilities():
self._gerar_relatorios_finais()
elif not self.relatorio.get_vulnerabilities():
print("Nenhuma vulnerabilidade encontrada. Relatórios não gerados.")
else:
print("Opção 'gerar relatórios' desativada. Relatórios não gerados.")
return self.relatorio.get_vulnerabilities()
def _gerar_relatorios_finais(self):
"""
Gera os relatórios HTML e PDF com todas as vulnerabilidades coletadas.
"""
print("\nGerando relatórios...")
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
report_name_base = f"analise_seguranca_{timestamp}"
self.relatorio.gerar_html(f"{report_name_base}.html")
self.relatorio.gerar_pdf(f"{report_name_base}.pdf")
print(f"Relatórios gerados com sucesso na pasta: {self.relatorio.diretorio_saida}")
# Bloco de execução principal (interface de linha de comando ou CI/CD)
if __name__ == "__main__":
vul_config_json_path = os.path.join(os.path.dirname(__file__), 'Vul', 'php_vulnerabilities.json')
output_report_dir = "report"
analisador = AnalisadorEstatico(vul_config_json_path, diretorio_saida=output_report_dir)
args = sys.argv[1:]
generate_reports_final = True
output_format_final = "text"
# Processar argumentos da linha de comando
if "--no-report" in args:
generate_reports_final = False
args.remove("--no-report")
if "--formato" in args:
try:
format_index = args.index("--formato")
output_format_final = args[format_index + 1]
if output_format_final not in ["text", "json"]:
print(f"Erro: Formato de saída '{output_format_final}' inválido. Use 'text' ou 'json'.")
sys.exit(1)
# Remove o argumento e seu valor da lista
args.pop(format_index)
args.pop(format_index)
except (ValueError, IndexError):
print("Erro: Argumento --formato requer um valor ('text' ou 'json').")
sys.exit(1)
input_paths_from_cli = args
if not input_paths_from_cli:
print("Erro: Nenhum arquivo ou diretório para analisar fornecido.")
print("Uso: python script.py <caminho1> [caminho2...] [--no-report] [--formato <text|json>]")
sys.exit(1)
actual_files_to_analyze = []
for p in input_paths_from_cli:
if not os.path.exists(p):
if output_format_final != "json":
print(f"Aviso: Caminho '{p}' não encontrado. Ignorando.", file=sys.stderr)
continue
collected = collect_php_files_from_path(p)
if not collected and output_format_final != "json":
print(f"Aviso: Nenhum arquivo PHP encontrado em '{p}'. Ignorando.", file=sys.stderr)
actual_files_to_analyze.extend(collected)
if not actual_files_to_analyze:
if output_format_final != "json":
print("Erro: Nenhum arquivo PHP válido encontrado para análise nos caminhos fornecidos. Abortando.")
print("Uso: python script.py <caminho1> [caminho2...] [--no-report] [--formato <text|json>]")
sys.exit(1)
if output_format_final != "json":
print(f"Modo de linha de comando: Analisando {len(actual_files_to_analyze)} arquivo(s).")
vulnerabilidades = analisador.analisar_multiplos_arquivos_php(
actual_files_to_analyze,
generate_reports=generate_reports_final,
output_format=output_format_final
)
if output_format_final == "json":
# Converte a lista de vulnerabilidades para um formato serializável
json_output = [v.to_dict() for v in vulnerabilidades]
print(json.dumps(json_output, indent=4))
else:
print("\nAnálise concluída.")