From 53c4898efe8d80ec6790e0d861ba57f1e498b243 Mon Sep 17 00:00:00 2001 From: jelly Tomas Date: Sun, 31 May 2026 22:00:19 +0100 Subject: [PATCH] kys7 --- relatorio/relatorio.tex | 202 +++++++++++++++++++++++++++++++++------- 1 file changed, 169 insertions(+), 33 deletions(-) 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}