Introdução
O XSS (Cross-Site Scripting) é uma das vulnerabilidades mais comuns e perigosas que afetam aplicações web, incluindo o WordPress. Plugins mal desenvolvidos, sem proteção adequada, podem permitir que invasores injetem scripts maliciosos capazes de roubar sessões, redirecionar usuários ou manipular o conteúdo do site.
Este artigo apresenta um guia completo, prático e técnico sobre como proteger plugins WordPress contra ataques XSS, aplicando as melhores práticas de segurança nativas da plataforma.
O que é XSS?
O XSS (Cross-Site Scripting) permite que atacantes injetem scripts maliciosos em páginas visualizadas por outros usuários. Ele se divide principalmente em:
- XSS Refletido: o código malicioso é refletido na resposta do servidor (ex: via
$_GET). - XSS Persistente: o código malicioso é armazenado no banco de dados e executado por todos que acessarem o conteúdo.
- XSS DOM-Based: o script é executado apenas no lado do cliente, manipulado via JavaScript.
Como Proteger um Plugin WordPress Contra XSS
Para garantir que seu plugin esteja protegido, você deve aplicar três pilares de segurança:
1. Sanitização de Entrada (Input Sanitization)
Evita que dados maliciosos sejam processados ou armazenados no banco.
Funções recomendadas:
| Função | Uso |
|---|---|
sanitize_text_field() | Remove HTML e espaços extras. Ideal para inputs simples. |
sanitize_email() | Verifica se o valor é um e-mail válido. |
sanitize_textarea_field() | Sanitiza textos longos. |
sanitize_key() | Para slugs, chaves e identificadores. |
sanitize_file_name() | Limpa nomes de arquivos. |
sanitize_user() | Sanitiza nomes de usuário. |
Exemplo:
phpCopiarEditar$nome = sanitize_text_field($_POST['nome']);
2. Escape de Saída (Output Escaping)
Garante que o conteúdo seja exibido como texto, não executado como código.
Funções recomendadas:
| Função | Uso |
|---|---|
esc_html() | Para conteúdos visíveis em HTML. |
esc_attr() | Para atributos HTML (ex: value). |
esc_url() | Para links e redirecionamentos. |
esc_js() | Para strings usadas dentro de scripts JS. |
wp_kses() | Permite apenas certas tags e atributos. |
wp_kses_post() | Versão mais permissiva, ideal para posts. |
Exemplo:
phpCopiarEditarecho esc_html($comentario);
3. ✔️ Validação
Sanitizar remove conteúdo perigoso, mas validar impede que dados incorretos entrem no sistema.
Exemplo:
phpCopiarEditarif (!is_email($email)) {
wp_die("E-mail inválido.");
}
Filtrando HTML com Segurança
Se você quiser permitir algumas tags (como <b>, <i>, <strong>), utilize:
phpCopiarEditar$seguro = wp_kses($comentario, [
'b' => [],
'i' => [],
'strong' => [],
'em' => []
]);
Protegendo URLs
Nunca exiba diretamente valores vindos de $_GET, $_POST ou outras entradas externas em atributos de links:
phpCopiarEditarecho '<a href="' . esc_url($_GET['url']) . '">Clique aqui</a>';
Cabeçalhos de Segurança Recomendados
Além das boas práticas no PHP, você pode adicionar cabeçalhos HTTP de segurança para reforçar a proteção no navegador:
phpCopiarEditarheader("Content-Security-Policy: default-src 'self'");
header("X-XSS-Protection: 1; mode=block");
header("X-Content-Type-Options: nosniff");
Ou configure via .htaccess ou nginx:
apacheCopiarEditarHeader set Content-Security-Policy "default-src 'self'"
Ferramentas de Auditoria
- WPScan (CLI): para encontrar vulnerabilidades conhecidas.
- Burp Suite / ZAP: para testes manuais e fuzzing.
- Wordfence / iThemes Security: para hardening no ambiente WordPress.
- Static Analyzers: como SonarQube ou CodeQL para revisão de código.
✅ Checklist de Proteção Contra XSS
| ✅ | Item |
|---|---|
| ⬜ | Usar sanitize_* em toda entrada ($_POST, $_GET, $_REQUEST) |
| ⬜ | Usar esc_* em toda saída visível ou que vá para atributos HTML |
| ⬜ | Validar dados com is_email, is_numeric, in_array, etc. |
| ⬜ | Evitar ecoar diretamente $_GET, $_POST sem filtragem |
| ⬜ | Se HTML for necessário, usar wp_kses com whitelist |
| ⬜ | Testar com payloads como <script>alert(1)</script> e <img src=x onerror=alert(1)> |
Exemplo Completo de Código Seguro
phpCopiarEditarif (isset($_POST['comentario'])) {
$comentario = sanitize_textarea_field($_POST['comentario']);
global $wpdb;
$wpdb->insert("{$wpdb->prefix}comentarios_seguro", ['comentario' => $comentario]);
}
$comentarios = $wpdb->get_results("SELECT * FROM {$wpdb->prefix}comentarios_seguro");
foreach ($comentarios as $c) {
echo '<p>' . esc_html($c->comentario) . '</p>';
}
Conclusão
Proteger seu plugin contra XSS não é apenas uma recomendação — é uma obrigação ética e profissional. Ao aplicar as boas práticas listadas neste artigo, você fortalece a segurança do seu projeto, protege seus usuários e evita exposições críticas que poderiam ser exploradas por atacantes.
