Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
132 changes: 132 additions & 0 deletions XSS_detection-main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
# -*- coding: utf-8 -*-
"""mainsql-autoencoder.ipynb

Automatically generated by Colab.

Original file is located at
https://colab.research.google.com/drive/1cXWyb8QCCnNhwPSI-An__38RDP1fRi0s
"""

import numpy as np
import pandas as pd
from sklearn.metrics import classification_report, confusion_matrix
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
import tensorflow as tf
from tensorflow.keras.models import Model
from tensorflow.keras.layers import Input, Dense

#1 Carrega o dataset de treino
df_treino = pd.read_csv("XSSTraining.csv")

# Separa os dados em variáveis independentes (X) e a variável alvo (y):
X = df_treino.drop("Class", axis=1) # Remove a coluna "Class" para usar como entrada
y = df_treino["Class"].apply(lambda x: 1 if x == "Malicious" else 0) # Converte rótulo para binário: 1 = ataque, 0 = normal

#2 Divide os dados em treino e teste, mantendo a proporção das classes
X_treino, X_teste, y_treino, y_teste = train_test_split(
X, y, test_size=0.2, random_state=42, stratify=y # 20% para teste, estratificado por classe
)

#3 Normaliza apenas os dados normais do conjunto de treino
escala = StandardScaler() # Inicializa o normalizador
X_treino_normal = X_treino[y_treino == 0] # Filtra apenas os dados normais
X_treino_normal_escala = escala.fit_transform(X_treino_normal) # Ajusta e transforma os dados normais
X_teste_escala = escala.transform(X_teste) # Aplica a mesma transformação ao conjunto de teste

#4 Define a arquitetura do Autoencoder
input_dim = X.shape[1] # Número de atributos de entrada
input_layer = Input(shape=(input_dim,)) # Camada de entrada

# Camadas de codificação
encoded = Dense(16, activation='relu')(input_layer)
encoded = Dense(8, activation='relu')(encoded)

# Camadas de decodificação
decoded = Dense(16, activation='relu')(encoded)
decoded = Dense(input_dim, activation='relu')(decoded) #Reconstrói a entrada

# Cria e compila o modelo Autoencoder
autoencoder = Model(inputs=input_layer, outputs=decoded)
autoencoder.compile(optimizer='adam', loss='mse') #Usa o erro como função de perda

#5 Treina o Autoencoder apenas com dados normais
autoencoder.fit(
X_treino_normal_escala, X_treino_normal_escala, #Entrada e saída são iguais
epochs=90, batch_size=32, shuffle=True, #Treinamento por 90 épocas/ciclos
validation_split=0.1, verbose=1 # Usa 10% dos dados normais para validação
)

#6 Calcula o erro de reconstrução no conjunto de teste
X_recalculo = autoencoder.predict(X_teste_escala) #Reconstrói os dados de teste
error = np.mean(np.square(X_teste_escala - X_recalculo), axis=1) #Erro de reconstrução por amostra

# Calcula o erro de reconstrução nos dados normais de treino
reco_treino = autoencoder.predict(X_treino_normal_escala)
mse_train = np.mean(np.square(X_treino_normal_escala - reco_treino), axis=1)

#7 Busca o melhor threshold para detectar ataques
porcentagens = range(70, 100, 2) #Testa thresholds entre 70 e 98
melhor_recall = 0
melhor_threshold = 0
melhor_resultado = {}

y_teste_numeric = y_teste.values #Converte para array NumPy

# Loop para testar diferentes thresholds
for x in porcentagens:
threshold = np.percentile(mse_train, x) #Define threshold com base no erro dos dados normais
prev_loop = [1 if i > threshold else 0 for i in error] #Classifica como ataque se erro > threshold

# Gera relatório de classificação
relatorio = classification_report(
y_teste_numeric, prev_loop,
target_names=["Normal", "Ataque"],
output_dict=True
)
recall_ataque = relatorio["Ataque"]["recall"] #Extrai o recall da classe "Ataque"

# Atualiza o melhor resultado se o recall for maior
if recall_ataque > melhor_recall:
melhor_recall = recall_ataque
melhor_threshold = threshold
melhor_resultado = {
"percentil": x,
"precision": relatorio["Ataque"]["precision"],
"recall": recall_ataque,
"f1": relatorio["Ataque"]["f1-score"],
"matriz_confusao": confusion_matrix(y_teste_numeric, prev_loop)
}

#8 Avaliação final no conjunto de teste original usando o melhor threshold
prev_y = [1 if e > melhor_threshold else 0 for e in error] # Classifica com base no melhor threshold

# Exibe os resultados
print("🔍 Avaliação no conjunto de teste original:")
print("Matriz de Confusão:")
print(confusion_matrix(y_teste_numeric, prev_y))

print("\nClassification Report:")
print(classification_report(y_teste_numeric, prev_y, target_names=["Normal", "Ataque"]))

print("\nMelhor Resultado encontrado:")
print(melhor_resultado)

#9 Avaliação com novo dataset XSStesting
df_xss = pd.read_csv("XSSTesting.csv")
y_xss = df_xss["Class"].apply(lambda x: 1 if x == "Malicious" else 0) #Converte rótulo para binário
X_xss = df_xss.drop("Class", axis=1) #Remove a coluna de classe

X_xss_escala = escala.transform(X_xss) #Normaliza os dados com o mesmo scaler
X_xss_reconstruido = autoencoder.predict(X_xss_escala) #Reconstrói os dados
erro_xss = np.mean(np.square(X_xss_escala - X_xss_reconstruido), axis=1) #Calcula erro de reconstrução

prev_xss = [1 if e > melhor_threshold else 0 for e in erro_xss] #Classifica com base no threshold ideal

# Resultado
print("\n🧪 Avaliação no dataset XSStesting:")
print("Matriz de Confusão:")
print(confusion_matrix(y_xss, prev_xss))

print("\nClassification Report:")
print(classification_report(y_xss, prev_xss, target_names=["Normal", "Ataque"]))