diff --git a/XSS_detection-main.py b/XSS_detection-main.py new file mode 100644 index 0000000..910312f --- /dev/null +++ b/XSS_detection-main.py @@ -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"]))