diff --git a/relatorio/relatorio.tex b/relatorio/relatorio.tex
index 3e7a787..ba4f127 100644
--- a/relatorio/relatorio.tex
+++ b/relatorio/relatorio.tex
@@ -27,15 +27,21 @@
Este trabalho tem como objetivo realizar testes de penetração numa aplicação
cobaia (o \textit{Juicebox}) desenhada para aprendizagem.
-Este trabalho tem como objetivo utilizar o \textbf{WSTG} (Web security testing guide) e configurar um ModSecurity reverse proxy como uma \textbf{WAF}.
-Para esse fim temos uma aplicação cobaia (o \textit{Juicebox}) desenhada para aprendizagem que vamos utilizar num ambiente controlado para aprender como descobrir vulnerabilidades (aplicando o \textbf{WSTG} e recorrendo ao \textbf{OWASP ZAP}) e prevenir antes do serviço estar online (elaborando uma \textbf{WAF}).
+Este trabalho tem como objetivo utilizar o \textbf{WSTG} (Web security
+testing guide) e configurar um ModSecurity reverse proxy como uma
+\textbf{WAF}. Para esse fim temos uma aplicação cobaia (o \textit{Juicebox})
+desenhada para aprendizagem que vamos utilizar num ambiente controlado
+para aprender como descobrir vulnerabilidades (aplicando o \textbf{WSTG}
+e recorrendo ao \textbf{OWASP ZAP}) e prevenir antes do serviço estar
+online (elaborando uma \textbf{WAF}).
\section{Architecture Considered for Both Stages}
Utilizámos somente duas máquinas virtuais: um servidor a correr \textit{CentOS 9}
e um cliente a correr \textit{Kali Linux}. O servidor contém o serviço \textit{Apache},
que age como \textit{firewall} através do módulo \textit{ModSecurity}, e um servidor
-\textit{Node.js} que aloja o \textit{Juicebox} --- a aplicação que vai servir de cobaia (\textit{dummy}).
+\textit{Node.js} que aloja o \textit{Juicebox} --- a aplicação que vai
+servir de cobaia (\textit{dummy}).
% Vão ser realizadas duas etapas de testes: primeiro, sem WAF (\textit{Web Application Firewall})
% e com foco em explorar vulnerabilidades na aplicação; e, posteriormente, com uma WAF configurada para
@@ -48,7 +54,9 @@ Com o ambiente criado foram realizadas duas etapas de testes:
\item \texttt{Primeira etapa}: Explorar vulnerabilidades na aplicação que existem sem a \textbf{WAF}
\item \texttt{Segunda etapa}:Verificar que vulnerabilidades foram mitigadas da primeira etapa com o uso de uma \textbf{WAF} configurada.
\end{itemize}
-Realisticamente estas etapas podiam continuar a repetir-se, até que estivessemos satisfeitos com o resultado, mas para o fim deste projeto estas etapas serão suficientes.
+Realisticamente estas etapas podiam continuar a repetir-se, até que
+estivessemos satisfeitos com o resultado, mas para o fim deste projeto
+estas etapas serão suficientes.
\subsection{Network structure}
@@ -78,7 +86,11 @@ Realisticamente estas etapas podiam continuar a repetir-se, até que estivessemo
\subsection{Information Gathering}
-Utilizámos a política por omissão (\textit{default policy}) para a realização do \textit{Active Scan} através do OWASP ZAP. Com esta abordagem, obtivemos múltiplos alertas automáticos. De forma a priorizar a análise, investigamos as alertas principais com base no maior nível de risco e grau de confiança reportados pela ferramenta.
+Utilizámos a política por omissão (\textit{default policy}) para a
+realização do \textit{Active Scan} através do OWASP ZAP. Com esta
+abordagem, obtivemos múltiplos alertas automáticos. De forma a priorizar
+a análise, investigamos as alertas principais com base no maior nível de
+risco e grau de confiança reportados pela ferramenta.
% Para conseguir informação inicial realizamos um \textit{Active Scan} através do \textit{OWASP ZAP}, o policy utilizado para esse scan foi \textit{Default Policy}. Foi obtido vários aletas automáticos devido a esse scan e decidimos investigar as alertas principais com base no nível de risco e grau de confiança reportado pela ferramenta.
@@ -88,9 +100,13 @@ Adicionalmente, realizámos testes de infraestrutura utilizando ferramentas esp
sqlmap -u "http://192.168.1.1:3000/rest/products/search?q=apple" -p q --level=5 --risk=3 --banner
\end{codeblock}
-Ao executar o \textit{sqlmap}, descobrimos que o sistema de gestão de base de dados subjacente é o \textit{SQLite}.
+Ao executar o \textit{sqlmap}, descobrimos que o sistema de gestão de
+base de dados subjacente é o \textit{SQLite}.
-Paralelamente, realizámos uma descoberta de ficheiros e diretórios através de técnicas de \textit{fuzzing} de URLs no OWASP ZAP recorrendo à lista de permissões da \textit{DirBuster}. Esta exploração revelou os seguintes endpoints publicamente expostos:
+Paralelamente, realizámos uma descoberta de ficheiros e diretórios
+através de técnicas de \textit{fuzzing} de URLs no OWASP ZAP recorrendo
+à lista de permissões da \textit{DirBuster}. Esta exploração revelou os
+seguintes endpoints publicamente expostos:
\begin{itemize}
\item \texttt{/ftp}: Servidor de armazenamento e transferência de ficheiros exposto. (Figura \ref{fig:ftp})
@@ -123,15 +139,25 @@ Paralelamente, realizámos uma descoberta de ficheiros e diretórios através de
\subsubsection*{Enumerate Infrastructure and Application Admin Interfaces}
-Identificámos e testámos o acesso ao endpoint \texttt{/api-docs} (\textit{Swagger UI}), validando que as interfaces de documentação interna do sistema e as definições da API estavam publicamente expostas sem qualquer tipo de controlo de acesso ou autenticação prévia.
+Identificámos e testámos o acesso ao endpoint \texttt{/api-docs}
+(\textit{Swagger UI}), validando que as interfaces de documentação
+interna do sistema e as definições da API estavam publicamente expostas
+sem qualquer tipo de controlo de acesso ou autenticação prévia.
\subsubsection*{Test HTTP Methods}
-Testámos os métodos HTTP permitidos pelo servidor através do envio de pedidos \texttt{OPTIONS}. Verificámos que o servidor aceita métodos potencialmente perigosos ou desnecessários para utilizadores comuns em rotas específicas, expandindo a superfície de ataque da aplicação.
+Testámos os métodos HTTP permitidos pelo servidor através do envio de
+pedidos \texttt{OPTIONS}. Verificámos que o servidor aceita métodos
+potencialmente perigosos ou desnecessários para utilizadores comuns em
+rotas específicas, expandindo a superfície de ataque da aplicação.
\subsubsection*{Test File Permission}
-Analisámos as permissões de acesso no diretório \texttt{/ftp}. Verificámos que a falta de restrições rígidas ao nível do sistema de ficheiros permite a qualquer utilizador anónimo listar o conteúdo de diretórios estruturais e descarregar ficheiros não indexados na interface principal da aplicação.
+Analisámos as permissões de acesso no diretório \texttt{/ftp}.
+Verificámos que a falta de restrições rígidas ao nível do sistema de
+ficheiros permite a qualquer utilizador anónimo listar o conteúdo de
+diretórios estruturais e descarregar ficheiros não indexados na
+interface principal da aplicação.
@@ -139,11 +165,19 @@ Analisámos as permissões de acesso no diretório \texttt{/ftp}. Verificámos q
\subsubsection*{Test Role Definitions}
-Efetuámos testes de manipulação de parâmetros do lado do cliente através das ferramentas de programador do navegador. Adicionámos manualmente os cookies \texttt{isAdmin} com o valor \texttt{true} e \texttt{role} com o valor \texttt{admin}. Após a atualização da página, não observámos qualquer escalonamento de privilégios, indicando que a aplicação não valida perfis administrativos com base nestes cookies específicos.
+Efetuámos testes de manipulação de parâmetros do lado do cliente através
+das ferramentas de programador do navegador. Adicionámos manualmente os
+cookies \texttt{isAdmin} com o valor \texttt{true} e \texttt{role} com o
+valor \texttt{admin}. Após a atualização da página, não observámos
+qualquer escalonamento de privilégios, indicando que a aplicação não
+valida perfis administrativos com base nestes cookies específicos.
\subsubsection*{Test User Registration Process}
-Utilizámos o OWASP ZAP para intercetar o tráfego de rede e definir um \textit{breakpoint} no pedido HTTP POST de registo de novos utilizadores. Modificámos o corpo do pedido JSON, injetando manualmente o parâmetro \texttt{"role":"admin"}:
+Utilizámos o OWASP ZAP para intercetar o tráfego de rede e definir um
+\textit{breakpoint} no pedido HTTP POST de registo de novos utilizadores.
+Modificámos o corpo do pedido JSON, injetando manualmente o parâmetro
+\texttt{"role":"admin"}:
\begin{codeblock}{json}
{
@@ -161,11 +195,19 @@ Utilizámos o OWASP ZAP para intercetar o tráfego de rede e definir um \textit{
}
\end{codeblock}
-O servidor backend processou o pedido sem validar se o utilizador possuía autorização para definir o seu próprio perfil, o que resultou na criação bem-sucedida de uma conta com permissões totais de administrador (\textit{Mass Assignment Vulnerability}).
+O servidor backend processou o pedido sem validar se o utilizador
+possuía autorização para definir o seu próprio perfil, o que resultou
+na criação bem-sucedida de uma conta com permissões totais de
+administrador (\textit{Mass Assignment Vulnerability}).
\subsubsection*{Testing for Account Enumeration and Guessable User Account}
-Ao tentar registar um utilizador com o e-mail \texttt{admin@juice-sh.op}, verificámos que a aplicação devolve uma mensagem de erro explícita indicando que o e-mail já se encontra registado no sistema. Este comportamento confirma a vulnerabilidade de enumeração de contas, permitindo a um atacante mapear quais os e-mails válidos na plataforma.
+Ao tentar registar um utilizador com o e-mail
+\texttt{admin@juice-sh.op}, verificámos que a aplicação devolve uma
+mensagem de erro explícita indicando que o e-mail já se encontra
+registado no sistema. Este comportamento confirma a vulnerabilidade de
+enumeração de contas, permitindo a um atacante mapear quais os e-mails
+válidos na plataforma.
\begin{figure}[h!]
\centering
@@ -176,12 +218,17 @@ Ao tentar registar um utilizador com o e-mail \texttt{admin@juice-sh.op}, verifi
\subsubsection*{Testing for Weak or Unenforced Username Policy}
-Após testar vários caracteres especiais no formulário de registo, criámos um utilizador com os seguintes dados nos campos de input:
+Após testar vários caracteres especiais no formulário de registo,
+criámos um utilizador com os seguintes dados nos campos de input:
\begin{itemize}
\item \textbf{E-mail:} \texttt{son'or1=1--@gmail.com}
\item \textbf{Nome/Campos Adicionais:} \texttt{
STRONG}
\end{itemize}
-A aplicação aceitou o registo sem validar a presença de carateres de injeção SQL ou tags HTML. Contudo, verificámos que é impossível efetuar login com esta conta posteriormente, uma vez que o processo de autenticação falha e resulta num erro genérico do tipo \texttt{[object Object]} no ecrã.
+A aplicação aceitou o registo sem validar a presença de carateres de
+injeção SQL ou tags HTML. Contudo, verificámos que é impossível efetuar
+login com esta conta posteriormente, uma vez que o processo de
+autenticação falha e resulta num erro genérico do tipo
+\texttt{[object Object]} no ecrã.
\begin{figure}[h!]
\centering
@@ -192,15 +239,27 @@ A aplicação aceitou o registo sem validar a presença de carateres de injeçã
\subsection{Authentication Testing}
-Realizámos testes de \textit{fuzzing} automatizado contra o formulário de login utilizando dicionários de credenciais. Identificámos que a aplicação não implementa mecanismos de bloqueio de conta ou limitação de taxa de pedidos \textit{rate limiting}, permitindo ataques contínuos de \textit{brute force}.
+Realizámos testes de \textit{fuzzing} automatizado contra o formulário
+de login utilizando dicionários de credenciais. Identificámos que a
+aplicação não implementa mecanismos de bloqueio de conta ou limitação
+de taxa de pedidos \textit{rate limiting}, permitindo ataques contínuos
+de \textit{brute force}.
\subsection{Authorization Testing}
-Testámos as permissões de acesso ao diretório \texttt{/ftp} e verificámos que o servidor está configurado para permitir nativamente apenas a visualização de ficheiros com as extensões \texttt{.md} e \texttt{.pdf}.
+Testámos as permissões de acesso ao diretório \texttt{/ftp} e
+verificámos que o servidor está configurado para permitir nativamente
+apenas a visualização de ficheiros com as extensões \texttt{.md} e
+\texttt{.pdf}.
-Seguidamente, explorámos falhas na validação de inputs através de uma injeção de \textit{Null Byte} codificado (\texttt{\%2500.md} ou \texttt{\%2500.pdf}). O ataque foi bem-sucedido e contornou a validação de extensões do servidor, garantindo o acesso e descarregamento de ficheiros confidenciais restritos: \texttt{encrypt.pyc} e \texttt{suspicious\_errors.yml}.
+Seguidamente, explorámos falhas na validação de inputs através de uma
+injeção de \textit{Null Byte} codificado (\texttt{\%2500.md} ou
+\texttt{\%2500.pdf}). O ataque foi bem-sucedido e contornou a validação
+de extensões do servidor, garantindo o acesso e descarregamento de
+ficheiros confidenciais restritos: \texttt{encrypt.pyc} e
+\texttt{suspicious\_errors.yml}.
\begin{figure}[h!]
\centering
@@ -217,13 +276,21 @@ Seguidamente, explorámos falhas na validação de inputs através de uma injeç
\subsection{Session Management Testing}
-Identificámos que o cookie \texttt{token}, responsável por armazenar o identificador da sessão ativa do utilizador, possui a flag \texttt{HttpOnly} configurada como \texttt{false}. A ausência desta proteção significa que o token está totalmente exposto e pode ser lido por scripts do lado do cliente, tornando a sessão criticamente vulnerável a roubo por Cross-Site Scripting (XSS).
+Identificámos que o cookie \texttt{token}, responsável por armazenar o
+identificador da sessão ativa do utilizador, possui a flag
+\texttt{HttpOnly} configurada como \texttt{false}. A ausência desta
+proteção significa que o token está totalmente exposto e pode ser lido
+por scripts do lado do cliente, tornando a sessão criticamente vulnerável
+a roubo por Cross-Site Scripting (XSS).
\subsection{Input Validation Testing}
\subsubsection*{Testing for Reflected Cross Site Scripting}
-Durante a auditoria à barra de pesquisa de produtos, validámos a existência de uma vulnerabilidade de \textit{Reflected Cross-Site Scripting} (XSS) devido à ausência de higienização do input do utilizador.
+Durante a auditoria à barra de pesquisa de produtos, validámos a
+existência de uma vulnerabilidade de \textit{Reflected Cross-Site
+Scripting} (XSS) devido à ausência de higienização do input do
+utilizador.
\begin{enumerate}
\item \textbf{Injeção HTML:} Introduzimos o valor \texttt{apple} na pesquisa e verificámos que o resultado foi renderizado no navegador como um título estrutural, confirmando que o código HTML é injetado diretamente na página.
@@ -236,7 +303,9 @@ Durante a auditoria à barra de pesquisa de produtos, validámos a existência d
\end{enumerate}
\subsubsection{Testing for SQL Injection}
-Adicionalmente, explorámos o mesmo parâmetro de pesquisa recorrendo ao \textit{sqlmap} para validar falhas de injeção SQL, conseguindo extrair com sucesso a estrutura de 22 tabelas da base de dados:
+Adicionalmente, explorámos o mesmo parâmetro de pesquisa recorrendo ao
+\textit{sqlmap} para validar falhas de injeção SQL, conseguindo extrair
+com sucesso a estrutura de 22 tabelas da base de dados:
\begin{codeblock}{bash}
sqlmap -u "http://10.60.0.1:3000/rest/products/search?q=apple" -p q --dbms=sqlite --prefix="'%" --suffix="%'--" --tables --batch
@@ -269,11 +338,21 @@ sqlmap -u "http://10.60.0.1:3000/rest/products/search?q=apple" -p q --dbms=sqlit
\end{codeblock}
-Apesar de não ter sido detetado pelo active scan foi feito fuzzing nos detalhes de login para saber se estava vulneravel a esse tipo de ataques visto que existia essa vulnerabilidade noutros paremetros. Verificamos que de facto também estava vulneravel a SQL Injection, e que a resposta era a tabela com o
+Apesar de não ter sido detetado pelo active scan foi feito fuzzing nos
+detalhes de login para saber se estava vulneravel a esse tipo de ataques
+visto que existia essa vulnerabilidade noutros paremetros. Verificamos
+que de facto também estava vulneravel a SQL Injection, e que a resposta
+era a tabela com o
\subsection{Testing for Error Handling}
-Ao tentar forçar o acesso a uma página ou ficheiro inexistente no servidor de ficheiros, como por exemplo na rota \texttt{/ftp/teste}, a aplicação falhou ao tratar a exceção de forma segura. Em vez de apresentar uma página de erro genérica (404), o servidor devolveu uma resposta detalhada expondo o \textit{stack trace} completo do ambiente \textit{Express.js}, revelando caminhos internos do sistema de ficheiros do servidor.
+Ao tentar forçar o acesso a uma página ou ficheiro inexistente no
+servidor de ficheiros, como por exemplo na rota \texttt{/ftp/teste},
+a aplicação falhou ao tratar a exceção de forma segura. Em vez de
+apresentar uma página de erro genérica (404), o servidor devolveu uma
+resposta detalhada expondo o \textit{stack trace} completo do ambiente
+\textit{Express.js}, revelando caminhos internos do sistema de ficheiros
+do servidor.
@@ -286,7 +365,11 @@ Ao tentar forçar o acesso a uma página ou ficheiro inexistente no servidor de
\subsection{Client Side Testing}
-Validámos que o token de sessão (JWT) do utilizador autenticado está armazenado diretamente no \texttt{localStorage} do navegador. Uma vez que o \texttt{localStorage} não possui mecanismos de proteção equivalentes à flag \texttt{HttpOnly} dos cookies, qualquer script executado no contexto da página consegue ler estes dados.
+Validámos que o token de sessão (JWT) do utilizador autenticado está
+armazenado diretamente no \texttt{localStorage} do navegador. Uma vez
+que o \texttt{localStorage} não possui mecanismos de proteção
+equivalentes à flag \texttt{HttpOnly} dos cookies, qualquer script
+executado no contexto da página consegue ler estes dados.
Utilizando a falha de XSS identificada anteriormente na barra de pesquisas, injetámos o seguinte payload direcionado:
@@ -294,12 +377,25 @@ Utilizando a falha de XSS identificada anteriormente na barra de pesquisas, inje
apple
\end{codeblock}
-A execução deste vetor permitiu extrair o conteúdo do token diretamente do armazenamento local da vítima. Isto prova que um atacante pode automatizar a exfiltração destas informações e assumir a identidade de qualquer utilizador afetado sem necessitar de saber as credenciais de acesso de forma persistente.
+A execução deste vetor permitiu extrair o conteúdo do token diretamente
+do armazenamento local da vítima. Isto prova que um atacante pode
+automatizar a exfiltração destas informações e assumir a identidade de
+qualquer utilizador afetado sem necessitar de saber as credenciais de
+acesso de forma persistente.
\section{Web Application Security Firewall}
\begin{codeblock}{modsecurity.conf}
+SecRuleEngine On
+SecRequestBodyAccess On
+SecResponseBodyAccess Off
+SecDebugLog /var/log/modsecurity/debug.log
+SecDebugLogLevel 0
+SecAuditLogParts ABIJ
+SecAuditLogType Serial
+SecAuditLog /var/log/modsecurity/audit.log
+
# sql injection
SecRule ARGS "['\";]|--" \
"id:950001,phase:2,deny,status:403,msg:'SQL Injection Attack Detected',log"
@@ -349,7 +445,13 @@ A regra de XSS/injeção HTML (id:950003) bloqueia eficazmente o registo de util
com tags HTML nos campos de \textit{input}, como \texttt{STRONG}, devolvendo um erro
\texttt{403 Forbidden} antes que o pedido chegue à aplicação.
-A vulnerabilidade de escalonamento de permissões (injeção do campo \texttt{"role":"admin"} no corpo JSON do registo) \textbf{não é mitigada pelas regras atuais}, visto que nenhuma delas valida a presença de campos não autorizados no corpo do pedido. A enumeração de contas via mensagens de erro da aplicação também permanece sem mitigação ao nível da WAF.
+A vulnerabilidade de escalonamento de permissões (injeção do campo
+\texttt{"role":"admin"} no corpo JSON do registo) \textbf{é mitigada
+pela regra id:950006}, que deteta a sequência
+\texttt{"role".*:.*"admin"} nos argumentos do pedido e devolve
+\texttt{403 Forbidden}, impedindo a criação de contas com perfil de
+administrador. A enumeração de contas via mensagens de erro da aplicação
+permanece sem mitigação ao nível da WAF.
\subsection{Authentication Testing}
@@ -362,24 +464,58 @@ tentativas falhadas permanece fora do âmbito da WAF, exigindo lógica aplicacio
\subsection{Authorization Testing}
-O ataque de \textit{Null Byte} (\texttt{\%2500.pdf}) utilizado para contornar
- a validação de extensões de ficheiro no diretório \texttt{/ftp} não é diretamente mitigado pelas regras configuradas, pois o payload não contém nenhum dos padrões definidos (e.g., \texttt{../}, \texttt{ftp} como argumento). A regra id:950007 teria de ser estendida para incluir sequências de \textit{null byte} codificadas (\texttt{\%00}, \texttt{\%2500}) para cobrir este vetor de ataque.
+O ataque de \textit{Null Byte} (\texttt{\%2500.pdf}) utilizado para
+contornar a validação de extensões de ficheiro no diretório
+\texttt{/ftp} não é diretamente mitigado pelas regras configuradas,
+pois o payload não contém nenhum dos padrões definidos (e.g.,
+\texttt{../}, \texttt{ftp} como argumento). A regra id:950007 teria de
+ser estendida para incluir sequências de \textit{null byte} codificadas
+(\texttt{\%00}, \texttt{\%2500}) para cobrir este vetor de ataque.
\subsection{Session Management Testing}
-A configuração da WAF não tem capacidade de alterar os atributos dos cookies definidos pela aplicação. A flag \texttt{HttpOnly} do cookie \texttt{token} continua ausente, uma vez que esta é uma propriedade definida pela camada aplicacional do \textit{JuiceShop}. Ainda assim, a mitigação do XSS (id:950003), descrita na subsecção seguinte, reduz indiretamente o risco de roubo de sessão ao bloquear os vetores que permitiriam a sua exploração.
+A configuração da WAF não tem capacidade de alterar os atributos dos
+cookies definidos pela aplicação. A flag \texttt{HttpOnly} do cookie
+\texttt{token} continua ausente, uma vez que esta é uma propriedade
+definida pela camada aplicacional do \textit{JuiceShop}. Ainda assim,
+a mitigação do XSS (id:950003), descrita na subsecção seguinte, reduz
+indiretamente o risco de roubo de sessão ao bloquear os vetores que
+permitiriam a sua exploração.
\subsection{Input Validation Testing}
-A regra de SQL Injection (id:950001) bloqueia com sucesso pedidos ao endpoint de pesquisa de produtos que contenham caracteres como \texttt{'}, \texttt{"}, \texttt{;} ou a sequência \texttt{--}, devolvendo \texttt{403 Forbidden}. O payload utilizado pelo \textit{sqlmap} é interceptado nesta fase, impedindo a extração de dados da base de dados. A regra de XSS/injeção HTML (id:950003) bloqueia igualmente os payloads com tags \texttt{
} e \texttt{}, neutralizando ambos os vetores de \textit{Reflected XSS} identificados na primeira etapa.
+A regra de SQL Injection (id:950001) bloqueia com sucesso pedidos ao
+endpoint de pesquisa de produtos que contenham caracteres como
+\texttt{'}, \texttt{"}, \texttt{;} ou a sequência \texttt{--},
+devolvendo \texttt{403 Forbidden}. O payload utilizado pelo
+\textit{sqlmap} é interceptado nesta fase, impedindo a extração de dados
+da base de dados. A regra de XSS/injeção HTML (id:950003) bloqueia
+igualmente os payloads com tags
+\texttt{
} e \texttt{}, neutralizando
+ambos os vetores de \textit{Reflected XSS} identificados na primeira
+etapa.
\subsection{Testing for Error Handling}
-A WAF atua sobre os pedidos antes de estes chegarem à aplicação, mas não filtra as respostas do servidor, uma vez que a diretiva \texttt{SecResponseBodyAccess} se encontra configurada como \texttt{Off}. Por consequência, a exposição do \textit{stack trace} do \textit{Express.js} em rotas inexistentes (e.g., \texttt{/ftp/teste}) não é mitigada. Para suprimir respostas de erro detalhadas seria necessário ativar a inspeção do corpo da resposta e definir regras sobre o seu conteúdo, ou configurar páginas de erro personalizadas no Apache.
+A WAF atua sobre os pedidos antes de estes chegarem à aplicação, mas
+não filtra as respostas do servidor, uma vez que a diretiva
+\texttt{SecResponseBodyAccess} se encontra configurada como
+\texttt{Off}. Por consequência, a exposição do \textit{stack trace} do
+\textit{Express.js} em rotas inexistentes (e.g., \texttt{/ftp/teste})
+não é mitigada. Para suprimir respostas de erro detalhadas seria
+necessário ativar a inspeção do corpo da resposta e definir regras sobre
+o seu conteúdo, ou configurar páginas de erro personalizadas no Apache.
\subsection{Client Side Testing}
-O payload de exfiltração do token JWT via XSS (\texttt{
}) é bloqueado pela regra id:950003, uma vez que contém a expressão \texttt{<.*>} nos argumentos do pedido de pesquisa. Desta forma, a cadeia de ataque identificada na primeira etapa --- que combinava a falha de XSS com o armazenamento inseguro do token --- é eficazmente neutralizada pela WAF ao nível da injeção inicial, impedindo a execução do código malicioso no contexto do navegador da vítima.
+O payload de exfiltração do token JWT via XSS
+(\texttt{
})
+é bloqueado pela regra id:950003, uma vez que contém a expressão
+\texttt{<.*>} nos argumentos do pedido de pesquisa. Desta forma, a
+cadeia de ataque identificada na primeira etapa --- que combinava a
+falha de XSS com o armazenamento inseguro do token --- é eficazmente
+neutralizada pela WAF ao nível da injeção inicial, impedindo a execução
+do código malicioso no contexto do navegador da vítima.
\section{Conclusions}