This commit is contained in:
jelly Tomas
2026-05-31 22:00:19 +01:00
parent c7b5f0e436
commit 53c4898efe

View File

@@ -27,15 +27,21 @@
Este trabalho tem como objetivo realizar testes de penetração numa aplicação Este trabalho tem como objetivo realizar testes de penetração numa aplicação
cobaia (o \textit{Juicebox}) desenhada para aprendizagem. 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}. Este trabalho tem como objetivo utilizar o \textbf{WSTG} (Web security
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}). 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} \section{Architecture Considered for Both Stages}
Utilizámos somente duas máquinas virtuais: um servidor a correr \textit{CentOS 9} 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}, 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 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}) % 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 % 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{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. \item \texttt{Segunda etapa}:Verificar que vulnerabilidades foram mitigadas da primeira etapa com o uso de uma \textbf{WAF} configurada.
\end{itemize} \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} \subsection{Network structure}
@@ -78,7 +86,11 @@ Realisticamente estas etapas podiam continuar a repetir-se, até que estivessemo
\subsection{Information Gathering} \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. % 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 sqlmap -u "http://192.168.1.1:3000/rest/products/search?q=apple" -p q --level=5 --risk=3 --banner
\end{codeblock} \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} \begin{itemize}
\item \texttt{/ftp}: Servidor de armazenamento e transferência de ficheiros exposto. (Figura \ref{fig:ftp}) \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} \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} \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} \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} \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} \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} \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} \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} \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!] \begin{figure}[h!]
\centering \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} \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} \begin{itemize}
\item \textbf{E-mail:} \texttt{son'or1=1--@gmail.com} \item \textbf{E-mail:} \texttt{son'or1=1--@gmail.com}
\item \textbf{Nome/Campos Adicionais:} \texttt{<h1>STRONG} \item \textbf{Nome/Campos Adicionais:} \texttt{<h1>STRONG}
\end{itemize} \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!] \begin{figure}[h!]
\centering \centering
@@ -192,15 +239,27 @@ A aplicação aceitou o registo sem validar a presença de carateres de injeçã
\subsection{Authentication Testing} \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} \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!] \begin{figure}[h!]
\centering \centering
@@ -217,13 +276,21 @@ Seguidamente, explorámos falhas na validação de inputs através de uma injeç
\subsection{Session Management Testing} \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} \subsection{Input Validation Testing}
\subsubsection*{Testing for Reflected Cross Site Scripting} \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} \begin{enumerate}
\item \textbf{Injeção HTML:} Introduzimos o valor \texttt{<h1>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. \item \textbf{Injeção HTML:} Introduzimos o valor \texttt{<h1>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} \end{enumerate}
\subsubsection{Testing for SQL Injection} \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} \begin{codeblock}{bash}
sqlmap -u "http://10.60.0.1:3000/rest/products/search?q=apple" -p q --dbms=sqlite --prefix="'%" --suffix="%'--" --tables --batch 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} \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} \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} \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: 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
<img src="x" onerror="alert(localStorage.getItem('token'))">apple <img src="x" onerror="alert(localStorage.getItem('token'))">apple
\end{codeblock} \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} \section{Web Application Security Firewall}
\begin{codeblock}{modsecurity.conf} \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 # sql injection
SecRule ARGS "['\";]|--" \ SecRule ARGS "['\";]|--" \
"id:950001,phase:2,deny,status:403,msg:'SQL Injection Attack Detected',log" "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{<h1>STRONG}, devolvendo um erro com tags HTML nos campos de \textit{input}, como \texttt{<h1>STRONG}, devolvendo um erro
\texttt{403 Forbidden} antes que o pedido chegue à aplicação. \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} \subsection{Authentication Testing}
@@ -362,24 +464,58 @@ tentativas falhadas permanece fora do âmbito da WAF, exigindo lógica aplicacio
\subsection{Authorization Testing} \subsection{Authorization Testing}
O ataque de \textit{Null Byte} (\texttt{\%2500.pdf}) utilizado para contornar O ataque de \textit{Null Byte} (\texttt{\%2500.pdf}) utilizado para
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. 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} \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} \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{<img src="x" onerror="...">} e \texttt{<h1>}, 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{<img src="x" onerror="...">} e \texttt{<h1>}, neutralizando
ambos os vetores de \textit{Reflected XSS} identificados na primeira
etapa.
\subsection{Testing for Error Handling} \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} \subsection{Client Side Testing}
O payload de exfiltração do token JWT via XSS (\texttt{<img src="x" onerror="alert(localStorage.getItem('token'))">}) é 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{<img src="x" onerror="alert(localStorage.getItem('token'))">})
é 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} \section{Conclusions}