Looking to hire Laravel developers? Try LaraJobs

antibot-laravel maintained by marcelocardozo

Description
Sistema de detecção e bloqueio de bots, proxies e VPNs para Laravel
Last update
2026/05/20 18:39 (dev-main)
License
Downloads
12

Comments
comments powered by Disqus

Antibot para Laravel

Sistema de detecção e bloqueio de bots, proxies e VPNs para Laravel.

Detecta automaticamente ferramentas de automação (Selenium, Puppeteer, Playwright, Cypress, PhantomJS, etc.), analisa fingerprints do navegador, verifica proxies/VPNs via ProxyCheck.io e bloqueia visitantes suspeitos com base em um sistema de pontuação configurável.

Requisitos

  • PHP 8.2+
  • Laravel 11, 12 ou 13
  • Chave de API do ProxyCheck.io (gratuito)

Instalação

composer require marcelocardozo/antibot-laravel

Publicar configuração, migrations e assets:

php artisan vendor:publish --provider="MarceloCardozo\Antibot\AntibotServiceProvider"

Ou publicar separadamente:

# Apenas configuração
php artisan vendor:publish --tag=antibot-config

# Apenas migrations
php artisan vendor:publish --tag=antibot-migrations

# Apenas assets (JS)
php artisan vendor:publish --tag=antibot-assets

# Apenas views (templates)
php artisan vendor:publish --tag=antibot-views

Executar as migrations:

php artisan migrate

Configuração

Adicione ao .env:

ANTIBOT_PROXYCHECK_API_KEY=sua-chave-aqui
ANTIBOT_TEST_IP=192.145.220.95
Variável Descrição
ANTIBOT_PROXYCHECK_API_KEY Chave de API do ProxyCheck.io
ANTIBOT_TEST_IP IP usado em localhost para testes (substitui 127.0.0.1)

O arquivo config/antibot.php contém todas as opções:

return [
    'route_prefix'       => 'antibot',       // Prefixo das rotas
    'route_middleware'    => ['web'],          // Middleware das rotas
    'pagina_inicial'     => '/',              // Página onde o antibot faz detecção + redirect
    'redirect_url'       => '',               // Redirecionar após aprovação (vazio = libera a página)
    'enviar_dados'       => true,             // Enviar dados do visitante na query string do redirect
    'bloqueado_url'      => '',               // Bloqueados → 404 (vazio) ou URL customizada
    'tempo_minimo'       => 5000,             // Tempo mínimo de verificação (ms)
    'tela_carregamento'  => 'spinner',        // Template: 'spinner' ou 'cloudflare'
    'score_minimo'       => 50,               // Score mínimo para bloquear
    'bloquear_bot'       => true,             // Bloquear bots detectados
    'bloquear_proxy'     => true,             // Bloquear proxies
    'bloquear_vpn'       => true,             // Bloquear VPNs
    'paises_permitidos'  => ['BR'],           // Países permitidos (vazio = todos)
    'regras'             => [ ... ],          // 40+ regras de detecção com pontuação
];

Uso

Adicione a diretiva @antibot em todas as páginas Blade do seu site:

<!DOCTYPE html>
<html>
<head></head>
<body>
    @antibot

    <h1>Meu site</h1>
</body>
</html>

Comportamento por página

  • Página inicial (pagina_inicial no config): após aprovação, redireciona para redirect_url com os dados do visitante na query string (IP, cidade, navegador, etc.). Se enviar_dados for false, redireciona sem dados.
  • Demais páginas: após aprovação, simplesmente libera a página (remove o loading e exibe o conteúdo).
  • Bloqueados: em qualquer página, redireciona para bloqueado_url ou exibe o template 404.

Fluxo de verificação

  1. A página é ocultada e um loading é exibido
  2. 40+ verificações client-side são executadas
  3. APIs server-side analisam IP, proxy, VPN e User-Agent
  4. O resultado é salvo no banco de dados
  5. Se aprovado na pagina_inicial: redireciona para redirect_url
  6. Se aprovado em outra página: libera a página
  7. Se bloqueado: redireciona para bloqueado_url ou exibe 404

Redirecionamento

redirect_url — Após aprovação na página inicial

// config/antibot.php

// Padrão: não redireciona (libera a página)
'redirect_url' => '',

// Redireciona para outra página após aprovação
'redirect_url' => '/dashboard',

enviar_dados — Dados do visitante na query string

Quando enviar_dados é true (padrão), ao redirecionar para redirect_url, os dados do visitante são enviados como parâmetros na query string:

/dashboard?ip=177.0.0.1&city=Sao+Paulo&client_name=Chrome&os_name=Windows&...

Para desativar:

'enviar_dados' => false,

bloqueado_url — Visitantes bloqueados

// config/antibot.php

// Padrão: exibe o template 404 do pacote
'bloqueado_url' => '',

// Path relativo
'bloqueado_url' => '/acesso-negado',

// URL externa
'bloqueado_url' => 'https://google.com',

Facade

O pacote disponibiliza uma Facade para uso programático:

use MarceloCardozo\Antibot\Facades\Antibot;

// Resolver IP real do visitante
$ip = Antibot::resolveIp($request);

// Verificar proxy/VPN
$data = Antibot::check($ip);
// Retorna: ['ip', 'asn', 'provider', 'isocode', 'city', 'proxy', 'vpn', ...]

// Detectar dispositivo
$device = Antibot::detect($request->userAgent());
// Retorna: ['bot', 'client_name', 'device_type', 'os_name', ...]

// Flags de servidor suspeitas
$flags = Antibot::getServerFlags($request);
// Retorna: ['tool_ua', 'short_ua', 'no_accept_language', ...]

Model

O pacote registra o model Eloquent MarceloCardozo\Antibot\Models\Acesso que permite consultar os dados de detecção no seu código.

Campos disponíveis

Campo Tipo Descrição
id bigint ID auto-incremento
data_hora timestamp Data/hora do acesso
ip string IP do visitante
url text URL acessada
asn string ASN do provedor
hostname string Hostname do IP
provider string Provedor de internet
organisation string Organização
isocode string Código do país (BR, US, etc.)
regioncode string Código da região
city string Cidade
proxy string "yes" ou "no"
vpn string "yes" ou "no"
bot string "yes" ou "no"
client_name string Navegador (Chrome, Firefox, etc.)
client_type string Tipo do client (browser, app, etc.)
client_version string Versão do navegador
device_brand string Marca do dispositivo
device_model string Modelo do dispositivo
device_type string Tipo (desktop, smartphone, tablet)
os_name string Sistema operacional
os_platform string Plataforma
os_version string Versão do SO
os_family string Família do SO
bloqueado string "true" ou "false"
motivo_bloqueio text Motivo(s) do bloqueio
created_at timestamp Criado em
updated_at timestamp Atualizado em

Exemplo em Controller

<?php

namespace App\Http\Controllers;

use MarceloCardozo\Antibot\Models\Acesso;

class AntibotController extends Controller
{
    // Listar todos os acessos com paginação
    public function index()
    {
        $acessos = Acesso::latest()->paginate(20);

        return view('antibot.index', compact('acessos'));
    }

    // Detalhes de um acesso específico
    public function show(Acesso $acesso)
    {
        return view('antibot.show', compact('acesso'));
    }

    // Listar apenas bloqueados
    public function bloqueados()
    {
        $bloqueados = Acesso::where('bloqueado', 'true')
            ->latest()
            ->paginate(20);

        return view('antibot.bloqueados', compact('bloqueados'));
    }

    // Estatísticas
    public function stats()
    {
        $total = Acesso::count();
        $bloqueados = Acesso::where('bloqueado', 'true')->count();
        $aprovados = Acesso::where('bloqueado', 'false')->count();
        $proxies = Acesso::where('proxy', 'yes')->count();
        $vpns = Acesso::where('vpn', 'yes')->count();
        $bots = Acesso::where('bot', 'yes')->count();

        $hoje = Acesso::whereDate('created_at', today())->count();
        $bloqueadosHoje = Acesso::where('bloqueado', 'true')
            ->whereDate('created_at', today())
            ->count();

        return view('antibot.stats', compact(
            'total', 'bloqueados', 'aprovados',
            'proxies', 'vpns', 'bots',
            'hoje', 'bloqueadosHoje'
        ));
    }
}

Consultas úteis

use MarceloCardozo\Antibot\Models\Acesso;

// Últimos 10 acessos bloqueados
$bloqueados = Acesso::where('bloqueado', 'true')
    ->latest()
    ->take(10)
    ->get();

// Acessos de um IP específico
$acessos = Acesso::where('ip', '177.0.0.1')->get();

// Verificar se um IP está bloqueado
$estaBloqueado = Acesso::where('ip', '177.0.0.1')
    ->latest()
    ->first()
    ?->isBloqueado(); // true ou false

// Acessos por país
$porPais = Acesso::select('isocode')
    ->selectRaw('count(*) as total')
    ->groupBy('isocode')
    ->orderByDesc('total')
    ->get();

// Acessos com proxy ou VPN
$suspeitos = Acesso::where('proxy', 'yes')
    ->orWhere('vpn', 'yes')
    ->latest()
    ->get();

// Total de bloqueados hoje
$total = Acesso::where('bloqueado', 'true')
    ->whereDate('created_at', today())
    ->count();

// Acessos de um navegador específico
$chrome = Acesso::where('client_name', 'Chrome')->get();

// Acessos mobile bloqueados
$mobileBloqueados = Acesso::where('device_type', 'smartphone')
    ->where('bloqueado', 'true')
    ->get();

Regras de detecção

O sistema usa 40+ regras com pontuação individual. Quando a soma dos pontos atinge o score_minimo (padrão: 50), o visitante é bloqueado.

Automação direta (80 pts cada)

Regra Detecta
webdriver navigator.webdriver === true
chromedriver Variáveis $cdc_ injetadas pelo ChromeDriver
selenium Propriedades globais do Selenium
puppeteer __puppeteer_evaluation_script__
playwright __playwright, __pw_manual
cypress window.Cypress, window.cy
phantomjs callPhantom, _phantom
nightmare __nightmare
webdriverio wdio, __wdio
testcafe %testCafeDriverInstance%
browserless __browserless, __chrome_aws_lambda
stack_automacao Stack trace com nomes de ferramentas

Fingerprint e ambiente

Regra Pts Detecta
ua_suspeito 60 Keywords de bot no User-Agent
webdriver_patched 60 Undetected-chromedriver (getter customizado)
chrome_falso 30 UA diz Chrome mas window.chrome ausente
webgl_software 30 Renderer software (SwiftShader, Mesa)
tela_zero 30 Dimensões da tela = 0
canvas_vazio 25 Canvas renderiza imagem vazia
mobile_sem_touch 25 UA mobile sem suporte touch
sem_color_depth 20 Color depth inválido
platform_mismatch 20 UA e navigator.platform divergem
perm_inconsistente 20 Permissões inconsistentes
audio_vazio 20 Audio fingerprint vazio

Para a lista completa, consulte config/antibot.php.

Desativar uma regra

// config/antibot.php
'regras' => [
    'historico_curto' => ['ativo' => false, 'pts' => 5],  // desativada
    'webdriver'       => ['ativo' => true,  'pts' => 80],  // ativa
],

Templates de loading

Dois templates disponíveis, configuráveis em config/antibot.php:

  • spinner — Spinner minimalista (padrão)
  • cloudflare — Visual estilo Cloudflare security check
'tela_carregamento' => 'cloudflare',

Para personalizar, publique as views e edite em resources/views/vendor/antibot/templates/.

Rotas registradas

Método URI Descrição
GET /antibot/config Configuração pública (JSON)
GET /antibot/api/proxycheck Detecção de proxy/VPN
GET /antibot/api/device-detector Detecção de dispositivo
POST /antibot/api/salvar Salvar registro de acesso
GET /antibot/templates/{template} Templates (404, spinner, cloudflare)

O prefixo /antibot é configurável via config('antibot.route_prefix').

Licença

MIT