SYSADMIN JOURNAL / Linux · Networking · Security · HostingProcedure, appunti e soluzioni tecniche
Crowdsec

CrowdSec: rilevare e bloccare la paginazione profonda oltre pagina 100

Pubblicato il 12/11/2026

La paginazione profonda di endpoint HTTP può essere utilizzata per enumerare molti risultati, consumare risorse o raccogliere contenuti automaticamente. Uno scenario CrowdSec può intercettare richieste con parametro page maggiore di 100 e raggrupparle per indirizzo IP.

Scenario YAML

Creare il file /etc/crowdsec/scenarios/http-deep-pagination.yaml:

type: trigger
name: custom/http-deep-pagination
description: "Rileva richieste HTTP con page maggiore di 100"
filter: >-
  evt.Meta.service == 'http' &&
  evt.Meta.log_type == 'http_access-log' &&
  evt.Meta.source_ip != nil &&
  evt.Parsed.http_args != nil &&
  evt.Parsed.http_args matches '(^|&)page=0*(10[1-9]|1[1-9][0-9]|[2-9][0-9]{2}|[1-9][0-9]{3,})(&|$)'
groupby: evt.Meta.source_ip
blackhole: 5m
labels:
  service: http
  behavior: "http:scan"
  label: "Deep pagination"
  remediation: true

Quali richieste corrispondono?

La regular expression controlla il parametro page nella query string, con separatori & e anche zeri iniziali. I risultati attesi sono:

GET /catalogo?page=99          # non corrisponde
GET /catalogo?page=100         # non corrisponde
GET /catalogo?page=101         # corrisponde
GET /catalogo?page=0101        # corrisponde
GET /catalogo?sort=asc&page=250&lang=it  # corrisponde
GET /catalogo?page=1000        # corrisponde
GET /catalogo?pages=500        # non corrisponde

Il confronto richiede evt.Parsed.http_args, che deve essere valorizzato dai parser HTTP. Non tutti i formati di log espongono la query string nello stesso modo: controllare sempre un evento reale con cscli explain. La regex tratta valori numerici interi nel parametro page e non gestisce automaticamente le forme URL-encoded più particolari.

Significato delle direttive

  • evt.Meta.service == 'http' e http_access-log limitano lo scenario agli access log HTTP.
  • evt.Meta.source_ip != nil evita eventi senza IP sorgente.
  • type: trigger può generare un alert al primo URL che supera il limite; è opportuno quando una pagina oltre 100 è sicuramente vietata dall’applicazione.
  • blackhole: 5m evita di generare alert ripetitivi dello stesso bucket per cinque minuti; non determina quanto dura il ban.
  • labels.remediation: true consente ai profili CrowdSec di associare una decisione di blocco, se configurati per farlo.

Limiti e precauzioni

Non ogni richiesta con page=101 è malevola: in alcuni siti il parametro è perfettamente valido. Prima di distribuire questa regola su più virtual host, verificare quali applicazioni utilizzano page, se esistono esportazioni legittime e se sia più sensato limitarsi a endpoint selezionati. Se un reverse proxy usa query string normalizzate o riscritture, la corrispondenza può cambiare.

Per limitare il rischio di falsi positivi si possono adottare soglie di frequenza, whitelist mirate ai servizi di monitoraggio oppure filtri sull’endpoint. La durata della decisione di ban resta configurata nei profiles, non nel campo blackhole dello scenario.

Installazione e test

sudo crowdsec -t
sudo cscli explain --file /tmp/pagination-test.log --type apache2 --verbose
sudo cscli scenarios list | grep http-deep-pagination
sudo cscli alerts list
sudo cscli decisions list
# Se la configurazione è valida:
sudo systemctl reload crowdsec

Per il file /tmp/pagination-test.log usare righe di access log reali e rappresentative, verificando sia page=100 sia page=101 e almeno un endpoint applicativo lecito.

Disattivazione

sudo mv /etc/crowdsec/scenarios/http-deep-pagination.yaml /etc/crowdsec/scenarios/http-deep-pagination.yaml.disabled
sudo crowdsec -t && sudo systemctl reload crowdsec

Riferimenti tecnici: formato degli scenari e parser HTTP CrowdSec.