ModSecurity bloqueando aplicação legítima (HTTP 403)
Voltar para blog

ModSecurity bloqueando aplicação legítima (HTTP 403)

07/06/2026 · 5 min · Infraestrutura

O caso: aplicação legítima bloqueada com HTTP 403#

Ambiente: Servidor cPanel/WHM em AlmaLinux/CloudLinux Sintoma: Requisições legítimas retornando HTTP 403 Forbidden para um domínio específico Objetivo: Diagnosticar o bloqueio e desativar o ModSecurity para o domínio específico ou criar uma exceção fina de regra via SSH (sem interface gráfica do WHM)

O diagnóstico do 403 em logs do Apache /usr/local/apache/logs/error_log:

[Wed May 01 21:40:00.123456 2025] [:error] [pid 12345] [client 203.0.113.45:52341]
ModSecurity: Access denied with code 403 (phase 2).
Pattern match "(?i)(?:\\b(?:(?:s(?:elect\\b(?:.{1,100}?\\b(?:(?:length|count|top)\\b.
{1,100}?\\bfrom|from\\b.{1,100}?\\bwhere)|.*?\\b(?:d(?:ump\\b.*\\bfrom|ata_type)|
(?:to_(?:numbe|cha)|inst)r))|p_(?:(?:addextendedpro|sqlexe)c|(?:oacreat|prepar)e|
execute(?:sql)?|makewebtask)|ql_(?:longvarchar|variant))..." at ARGS:description.
[file "/etc/apache2/conf.d/modsec_vendor_configs/OWASP3/rules/REQUEST-942-APPLICATION-ATTACK-SQLI.rlz"]
[line "45"] [id "942100"] [rev ""] [msg "SQL Injection Attack Detected via libinjection"]
[data "Matched Data: ..."] [severity "CRITICAL"] [ver "OWASP_CRS/3.3.4"]
[hostname "meudominio.com.br"] [uri "/admin/api/content"] [unique_id "YzX9..."]

A aplicação usa campos de texto livre que acionam a regra OWASP 942100 (SQL Injection via libinjection). O false-positive é um campo de descrição legítimo com sintaxe SQL em documentação técnica.


O erro: anatomia do falha na whmapi1#

A primeira tentativa foi usar a API administrativa do WHM, conforme intuição natural de quem gerencia via CLI:

whmapi1 toggle_modsec_for_domain domain=meudominio.com.br state=0

Retorno completo da API:

---
metadata: 
  command: toggle_modsec_for_domain
  reason: Unknown app ("toggle_modsec_for_domain") requested for this version (1) of the API.
  result: 0
  version: 1

O campo reason é explícito: Unknown app ("toggle_modsec_for_domain"). O endpoint não existe na whmapi1.

Análise arquitetural: WHM API vs. UAPI - separação de escopos#

A confusão é compreensível porque tanto o WHM quanto o cPanel gerenciam o ModSecurity, mas em camadas diferentes da hierarquia:

WHM (Web Host Manager) - Escopo: SERVIDOR
│
│  whmapi1 / whm_api2
│  ├── Criar/remover contas cPanel
│  ├── Reiniciar serviços (Apache, MySQL, etc.)
│  ├── Configurar IP addresses
│  ├── Gerenciar ModSecurity GLOBALMENTE (enable/disable no servidor todo)
│  └── ❌ NÃO gerencia configurações por domínio/vhost individual
│
└── cPanel - Escopo: CONTA (usuário/domínio)
│
│  UAPI (uapi) - API v3 atual
│  ├── Gerenciar domínios addon e parked
│  ├── Criar email accounts
│  ├── Gerenciar databases
│  └── ✅ Módulo ModSecurity: enable/disable por domínio

Por que essa separação existe:

O ModSecurity por domínio é implementado através de diretivas no VirtualHost Apache específico de cada conta cPanel. A linha no httpd.conf gerada pelo cPanel/EasyApache é baseada em arquivos de include. A whmapi1 não tem acesso direto para operar em contexto de conta individual - esse é o domínio exclusivo da UAPI.


O protocolo de segurança e solução prática#

Passo 1 - identificar o proprietário do domínio#

/scripts/whoowns meudominio.com.br

Saída: meuusuario

O script /scripts/whoowns consulta o arquivo /etc/userdomains - um mapa plano domínio→usuário mantido pelo cPanel:

# Verificação manual alternativa
grep "meudominio.com.br" /etc/userdomains
# meudominio.com.br: meuusuario

Passo 2 - validação de falso positivo e triagem inicial#

Antes de efetuar alterações, valide se o endpoint realmente aciona o bloqueio com tráfego legítimo utilizando o curl:

curl -X POST https://meudominio.com.br/admin/api/content \
  -H "Content-Type: application/json" \
  -d '{"description": "teste"}' \
  -v 2>&1 | grep -i "403\|modsecurity"

Verifique se a assinatura da regra 942100 é a única ou a principal causadora dos bloqueios no domínio em questão:

grep "meudominio.com.br" /usr/local/apache/logs/error_log | grep "942100" | wc -l

Passo 3 - protocolo de backup pré-configuração#

Nunca altere arquivos de configuração ou rode comandos de rebuild sem antes garantir pontos de restauração:

# Criar backup completo do diretório de userdata
tar czf /root/modsec-backup-$(date +%Y%m%d).tar.gz /etc/apache2/conf.d/userdata/

# Fazer cópia de segurança do arquivo de modsec específico, se ele já existir
cp /etc/apache2/conf.d/userdata/ssl/2/meuusuario/meudominio.com.br/modsec.conf \
   /root/modsec.conf.bak.$(date +%Y%m%d) 2>/dev/null || echo "Nenhum arquivo modsec.conf existente para este domínio."

Passo 4 - alternativa recomendada: exceção fina de regra#

Em vez de desabilitar o ModSecurity completamente (o que exporia a aplicação a múltiplos ataques), edite ou crie o arquivo de userdata para aplicar uma exceção apenas para a regra 942100.

Diretório para HTTPS: /etc/apache2/conf.d/userdata/ssl/2/meuusuario/meudominio.com.br/modsec.conf

Diretório para HTTP (opcional, mas recomendado para consistência): /etc/apache2/conf.d/userdata/2/meuusuario/meudominio.com.br/modsec.conf

Exemplo de Exceção para o VHost Inteiro:

<IfModule mod_security2.c>
    # Desabilitar apenas a regra 942100 (SQL Injection via libinjection)
    SecRuleRemoveById 942100
</IfModule>

Exemplo de Exceção Restrita ao Endpoint Problemático (Ainda Mais Seguro):

<IfModule mod_security2.c>
    # Desabilitar a regra apenas no URI correspondente
    <LocationMatch "/admin/api/content">
        SecRuleRemoveById 942100
    </LocationMatch>
</IfModule>

Após editar os arquivos acima, reconstrua as configurações do Apache e recarregue o daemon:

# Validar e reconstruir a configuração do Apache
/scripts/rebuildhttpdconf

# Aplicar as mudanças sem derrubar conexões ativas
/usr/sbin/apachectl graceful

Solução alternativa: UAPI para desativação total (último recurso)#

Caso precise desativar completamente o ModSecurity para este domínio, execute a UAPI no contexto do usuário identificado:

uapi --user=meuusuario ModSecurity disable_domains domains=meudominio.com.br

Retorno completo de sucesso:

---
apiversion: 3
func: disable_domains
module: ModSecurity
result: 
  data: 
- 
  dependencies: []
  domain: meudominio.com.br
  enabled: 0
  exception: ~
  searchhint: ''
  type: main
  errors: ~
  messages: ~
  metadata: 
transformed: 1
  status: 1
  warnings: ~

O que acontece internamente após o comando da UAPI#

O cPanel realiza a seguinte sequência automatizada de operações:

1. Valida que meuusuario existe e é dono de meudominio.com.br
2. Cria (ou sobrescreve) o arquivo:
   /etc/apache2/conf.d/userdata/ssl/2/meuusuario/meudominio.com.br/modsec.conf
3. Escreve a diretiva SecRuleEngine Off:
   <IfModule mod_security2.c>
   SecRuleEngine Off
   </IfModule>
4. Replica a diretiva para a versão HTTP (non-SSL):
   /etc/apache2/conf.d/userdata/2/meuusuario/meudominio.com.br/modsec.conf
5. Executa automaticamente: /scripts/rebuildhttpdconf
6. Executa: /usr/sbin/apachectl graceful  ← reload sem quedas de conexões

Verificação pós-configuração e monitoramento#

Após realizar a alteração (seja via exceção fina ou desativação), siga estes passos de validação técnica:

  1. Testar o endpoint que estava bloqueado:
   curl -I https://meudominio.com.br/admin/api/content
   # Deve retornar HTTP 200 OK (ou o código esperado pela aplicação, não mais 403)
  1. Verificar se outras regras de segurança permanecem ativas (Teste de Blindagem):

Se você utilizou a Abordagem de Exceção Fina, envie um payload malicioso alternativo (como uma tag de script XSS) para garantir que o WAF bloqueia tentativas de ataque legítimas:

   curl -X POST https://meudominio.com.br/admin/api/content \
     -H "Content-Type: application/x-www-form-urlencoded" \
     -d "payload=<script>alert(1)</script>" \
     -w "%{http_code}\n" -o /dev/null
   # Deve retornar 403 (ModSecurity bloqueando o XSS de forma saudável)
  1. Pesquisar logs por novos erros:
   tail -50 /usr/local/apache/logs/error_log | grep "meudominio.com.br"

Triagem sistêmica avançada e módulos complementares#

1. Auditoria de outros domínios com ModSecurity desativado#

Verifique se há outras brechas de segurança de WAF na mesma conta de usuário:

uapi --user=meuusuario ModSecurity list_domains | grep -B1 -A2 "enabled: 0"

Verifique estatísticas das regras mais acionadas no servidor para entender o impacto global das regras do CRS:

grep "id \"" /usr/local/apache/logs/error_log | awk -F'id "' '{print $2}' | awk -F'"' '{print $1}' | sort | uniq -c | sort -rn | head -15

2. Verificação de módulos Apache adicionais#

Às vezes o cliente continua recebendo erros HTTP 403 ou timeouts devido a outros módulos de segurança ativos no Apache que também policiam conexões. Audite quais módulos estão ativos:

apachectl -M | grep -E "evasive|limitipconn|reqtimeout"

3. Configuração de logging de auditoria do ModSecurity#

Se os logs do Apache não mostrarem detalhes suficientes para diagnosticar falsos positivos complexos, garanta que a auditoria detalhada do ModSecurity esteja ativa para a requisição:

# No arquivo /etc/apache2/conf.d/modsec2.conf ou WHM ModSecurity Configure
SecAuditEngine RelevantOnly
SecAuditLogRelevantStatus "^(?:5|4(?!04))"
SecAuditLogParts ABIJDEFHX
SecAuditLog /var/log/apache2/modsec_audit.log
SecAuditLogType Serial

4. Verificação de versão#

Sempre documente a versão do ecossistema e das regras CRS instaladas para compatibilidade de sintaxe:

# Versão do cPanel/WHM
cat /usr/local/cpanel/version

# Versão do ModSecurity ativa no daemon
httpd -M | grep -i security
# Ou consulte o log de inicialização do Apache
grep -i "ModSecurity" /usr/local/apache/logs/error_log | head -n 5

Fluxo de decisão visual#

flowchart TD A[HTTP 403 em domínio] --> B{Verificar logs ModSecurity} B -->|Regra específica encontrada| C{É falso positivo?} C -->|Sim| D[Criar exceção para a regra específica] C -->|Não| E[Investigar aplicação / Tratar entrada] B -->|Sem logs do ModSecurity| F{Verificar outros módulos} D --> D1[SecRuleRemoveById 942100] D1 --> D2[Ou desativar para URL específica com LocationMatch] D2 --> G[Backup, Aplicar e rebuildhttpdconf] E --> H[Corrigir payload ou comportamento] F -->|evasive/limitipconn/reqtimeout| I[Ajustar regras do respectivo módulo] F -->|Nenhum módulo ativo| J[Verificar firewall/WAF externo] K[Desabilitar ModSecurity no domínio] --> L[Último recurso - SecRuleEngine Off] style K fill:#7f1d1d,stroke:#ef4444,color:#fff style L fill:#854d0e,stroke:#f59e0b,color:#fff

Checklist de troubleshooting ModSecurity#

## Checklist: ModSecurity 403 - diagnóstico e correção

### 1. Diagnóstico e triagem
- [ ] Verificar logs de erro do Apache: `tail -100 /usr/local/apache/logs/error_log | grep 403`
- [ ] Identificar a regra CRS (ID e arquivo correspondente) causadora do bloqueio
- [ ] Validar o falso positivo reproduzindo a requisição via `curl`
- [ ] Verificar se outros domínios da conta estão apresentando o mesmo comportamento

### 2. Solução e modelagem de regras
- [ ] Criar exceção para a regra específica via `SecRuleRemoveById` (preferencial)
- [ ] Restringir a exceção ao endpoint correto utilizando `<LocationMatch>`
- [ ] Desabilitar completamente o ModSecurity para o domínio (apenas como último recurso)

### 3. Implementação segura
- [ ] Gerar backup completo dos diretórios userdata: `tar czf /root/modsec-backup.tar.gz /etc/apache2/conf.d/userdata/`
- [ ] Criar ou modificar o arquivo `modsec.conf` no caminho userdata adequado (SSL e non-SSL)
- [ ] Reconstruir a configuração de vhosts: `/scripts/rebuildhttpdconf`
- [ ] Recarregar o Apache de forma suave: `/usr/sbin/apachectl graceful`

### 4. Validação técnica
- [ ] Testar o URI problemático e certificar o retorno HTTP esperado
- [ ] Auditar logs de erro para garantir a ausência de novos bloqueios na requisição
- [ ] Garantir o bloqueio ativo contra outros vetores (como XSS com `<script>`)
- [ ] Monitorar a estabilidade do domínio por 24h

### 5. Documentação e auditoria pós-configuração
- [ ] Registrar exceção criada, motivo do falso positivo e data de revisão
- [ ] Confirmar o status do domínio via UAPI
- [ ] Testar e documentar o procedimento de rollback

Plano de rollback#

Em caso de instabilidade, erros sintáticos detectados no reinício do serviço Apache, ou novos requisitos de segurança, siga este roteiro de rollback:

Rollback manual (restaurar do backup de userdata)#

Restaure os arquivos a partir da cópia de segurança gerada no início das alterações:

# Restaurar o arquivo individual
cp /root/modsec.conf.bak.YYYYMMDD /etc/apache2/conf.d/userdata/ssl/2/meuusuario/meudominio.com.br/modsec.conf

# Se o arquivo não existia originalmente, exclua o arquivo criado para remover a exceção:
rm -f /etc/apache2/conf.d/userdata/ssl/2/meuusuario/meudominio.com.br/modsec.conf
rm -f /etc/apache2/conf.d/userdata/2/meuusuario/meudominio.com.br/modsec.conf

# Reconstruir e recarregar o Apache
/scripts/rebuildhttpdconf
/usr/sbin/apachectl graceful

Rollback via API cPanel (reabilitar ModSecurity no domínio)#

Se você usou a UAPI para desativar o ModSecurity, você pode reativá-lo com:

uapi --user=meuusuario ModSecurity enable_domains domains=meudominio.com.br

Tabela de referência: whmapi1 vs. UAPI para ModSecurity#

AçãoFerramenta corretaComando
Desativar para 1 domíniouapiuapi --user=X ModSecurity disable_domains domains=Y
Reativar para 1 domíniouapiuapi --user=X ModSecurity enable_domains domains=Y
Listar status por contauapiuapi --user=X ModSecurity list_domains
Desativar globalmentewhmapi1whmapi1 modsec_disable_all_domains
Ver configuração globalwhmapi1whmapi1 modsec_get_settings
Ver log de audits ModSecwhmapi1whmapi1 modsec_get_log

Este artigo foi útil?

Deixe uma reação rápida para apoiar o conteúdo:

CC BY-NC

Este post está licenciado sob CC BY-NC.

Comentários

Participe da discussão abaixo.

0 comentários