Fraud Detection Patterns — Estensione cap. 46 (v5.15 → v5.16)
Stato: Proposta di estensione Pattern Analyzer Owner: Ingegnere TLC Akira Data: 2026-05-13 Riferimento docx: cap. 46.2 v5.15 (da estendere in v5.16)
1. Pattern attuali (cap. 46.2 v5.15) — sintesi
| # | Pattern | Trigger principale |
|---|---|---|
| 1 | Wangiri | Ring breve + callback verso premium |
| 2 | IRSF (International Revenue Share Fraud) | Volume anomalo verso destination premium pagate al terminator |
| 3 | SIM Box | Originator dichiarato internazionale ma A-number sequenziali da pool mobile locale |
| 4 | Ping calls | Spike CPS con duration <1s, ACD bassissima |
| 5 | Concentration | >X% traffico verso singolo prefisso/dest in finestra T |
| 6 | Temporal | Volume fuori distribuzione storica (ore notturne / weekend) |
| 7 | CLI Anomali | CLI non in formato E.164 valido, lunghezze fuori range, all-zero |
| 8 | MSRN leak | Mobile Station Roaming Number presenti in CDR di B-leg |
| 9 | Call Center | Pattern outbound massivo predictive dialer (duration distribution bi-modale) |
Tutti i pattern alimentano risk_score aggregato per Originator, soglie alert
LOW/MED/HIGH e azione automatica (warn / throttle / block).
2. Pattern aggiuntivi proposti (cap. 46.2 v5.16)
2.1 Pattern 10 — CLI Spoofing E.164-valido (cap. 46.2.10)
Descrizione: CLI ben formato E.164 ma incoerente con il
caller_id_format configurato sull'Originator. Es. Originator italiano (caller
id format ^\+39[0-9]{9,10}$) presenta CLI +447700900123.
Detection:
SELECT cdr.id, cdr.originator_id, cdr.cli
FROM cdr
JOIN originators o ON o.id = cdr.originator_id
WHERE cdr.started_at > now() - INTERVAL '1 hour'
AND cdr.cli !~ o.caller_id_format;
Peso baseline: 15 (per chiamata violante) Action: warn admin; non-block automatico (può essere legitimate use case di prefix forwarding, da review umana).
2.2 Pattern 11 — Robocalling / Mass Campaign (cap. 46.2.11)
Descrizione: 1 originator >100 CPS verso N-mila B-number distinti in finestra breve, ASR <10%, ACD <15s. Caratteristico di campagne di mass dialing (lecite o illecite — distinguere via review business).
Detection:
SELECT originator_id,
COUNT(*) AS attempts,
COUNT(DISTINCT dst) AS distinct_dst,
AVG(answered::int) AS asr,
AVG(duration_seconds) FILTER (WHERE answered) AS acd
FROM cdr
WHERE started_at > now() - INTERVAL '5 min'
GROUP BY originator_id
HAVING COUNT(DISTINCT dst) > 1000
AND AVG(answered::int) < 0.10;
Peso baseline: 25 Action: throttle CPS 50% se conferma su 2 finestre consecutive; alert HIGH se ASR <2% (probabile spam).
2.3 Pattern 12 — PBX Hacking (cap. 46.2.12)
Descrizione: Device customer compromesso, originator usa credenziali rubate. Sintomo tipico: traffico massivo notturno (locale 22:00-06:00) verso destination premium / international high-cost, originato da customer storicamente con profilo daytime business.
Detection (richiede baseline per customer):
WITH nightly_baseline AS (
SELECT originator_id,
destination_id,
percentile_cont(0.5) WITHIN GROUP (ORDER BY hourly_volume) AS median_night_vol
FROM cdr_hourly_rollup
WHERE hour_of_day_local BETWEEN 22 AND 6
AND started_at > now() - INTERVAL '30 days'
GROUP BY 1, 2
),
current_night AS (
SELECT originator_id, destination_id, COUNT(*) AS current_vol
FROM cdr
WHERE started_at > now() - INTERVAL '1 hour'
AND EXTRACT(HOUR FROM started_at AT TIME ZONE timezone(originator_id))
BETWEEN 22 AND 6
GROUP BY 1, 2
)
SELECT c.originator_id, c.destination_id, c.current_vol, b.median_night_vol
FROM current_night c
JOIN nightly_baseline b USING (originator_id, destination_id)
WHERE c.current_vol > 10 * GREATEST(b.median_night_vol, 1);
Peso baseline: 40 (alto — è breach di customer) Action: block immediato originator + alert Telegram NOC + email customer.
2.4 Pattern 13 — Toll Bypass Detection (cap. 46.2.13)
Descrizione: Chiamata da Originator internazionale (es. UK) verso destination locale dello stesso paese del device (es. Italia → Italia) con duration >5min. Indicatore di toll bypass / GSM gateway illegittimo che re-origina chiamate locali via trunk internazionale per evadere tariffe.
Detection:
SELECT cdr.id, o.country AS originator_country,
d.country_iso2 AS dest_country, cdr.duration_seconds
FROM cdr
JOIN originators o ON o.id = cdr.originator_id
JOIN destinations d ON d.id = cdr.destination_id
WHERE cdr.started_at > now() - INTERVAL '1 hour'
AND cdr.duration_seconds > 300
AND o.country <> d.country_iso2
AND d.country_iso2 IN ('IT','FR','DE','ES','UK','US'); -- mercati high-volume
Peso baseline: 20 Action: warn; richiede correlazione con Pattern 11/3 per escalation (toll bypass + SIM box è classico stack fraud).
2.5 Pattern 14 — TDoS (Telephony DoS) (cap. 46.2.14)
Descrizione: Flood verso singolo B-number da molte origini diverse, intent disruption del destinatario (call-center, hotline, emergency, business target). A differenza di IRSF qui il vettore è "bersaglio singolo, molti mittenti", non revenue share.
Detection:
SELECT dst,
COUNT(DISTINCT cli) AS distinct_cli,
COUNT(*) AS attempts
FROM cdr
WHERE started_at > now() - INTERVAL '1 hour'
GROUP BY dst
HAVING COUNT(DISTINCT cli) > 50;
Peso baseline: 30 Action: alert HIGH NOC, NON block automatico (il bersaglio può essere legittimo destinatario di campagna lecita — es. radio call-in show). Apertura ticket per review.
2.6 Pattern 15 — Velocity Check Nuovo Onboarding (cap. 46.2.15)
Descrizione: Originator creato <24h e già con CPS sustained >50. Pattern tipico di account fraudster appena onboardato che lancia subito campagne massive prima del review trust.
Detection:
SELECT o.id, o.name, o.created_at, o.current_cps
FROM originators o
WHERE o.created_at > now() - INTERVAL '24 hours'
AND o.current_cps > 50;
Peso baseline: 35
Action: throttle CPS a min(current, 20) finché Originator non supera
soglia trust (es. 72h con ASR >30%). Bypass possibile da admin con flag
trust_override = TRUE (audit-loggato).
3. Risk Score Formula aggiornata (cap. 46.3 v5.16)
Formula precedente (v5.15): somma pesata semplice dei pattern triggered. Limite: non scala con il volume; un singolo evento Wangiri ha lo stesso score di 1000 eventi Wangiri.
Nuova formula (v5.16):
risk_score = baseline_pattern_weight * (1 + log10(max(volume, 1)) /
log10(max(threshold, 10)))
Dove:
baseline_pattern_weight= peso del pattern (15-40, definito in §2).volume= numero eventi triggered del pattern nella finestra (default 1h).threshold= volume minimo per attivare il pattern (configurabile per pattern; default 10).
Risk score finale per Originator: somma dei risk_score di tutti i pattern
triggered, capped a 100.
Soglie alert e azioni:
| Score range | Severity | Azione default |
|---|---|---|
| 0–29 | OK | nessuna azione |
| 30–59 | LOW | log + notify NOC Telegram |
| 60–79 | MEDIUM | throttle CPS 50%, ticket auto-open |
| 80–100 | HIGH | block originator immediato, ticket P1 |
Soglie configurabili via system_settings.fraud_thresholds_*.
4. Esempio composito
Originator X trigger simultaneo:
- Pattern 4 (Ping calls), volume=200, threshold=50 → 10 * (1 + log10(200)/log10(50)) = 10 * 2.35 = 23.5
- Pattern 11 (Robocalling), volume=1500, threshold=1000 → 25 * (1 + log10(1500)/log10(1000)) = 25 * 2.06 = 51.5
- Pattern 12 (PBX Hacking), volume=12, threshold=10 → 40 * (1 + log10(12)/log10(10)) = 40 * 2.08 = 83.2
Score totale capped = 100 → HIGH severity → block immediato.
5. Patch da applicare a docx v5.16
- Cap. 46.2: aggiungere sub-paragrafi 46.2.10 → 46.2.15 con i 6 pattern proposti. Mantenere stesso layout (descrizione, detection SQL, peso, action) dei pattern esistenti 1-9.
- Cap. 46.3: sostituire formula risk_score con quella di §3 sopra; aggiornare tabella soglie alert.
- Cap. 46.4 (UI Pattern Analyzer): aggiungere card per i nuovi pattern nel dashboard fraud (toggle on/off per pattern, threshold tuning per customer/originator).
- Glossario: aggiungere voci TDoS, toll bypass, velocity check.
6. Taratura soglie e prefix list (TASK-539, 2026-06-10)
Le soglie vivono in pattern_detections.default_params (seed migration 0057,
tuning 0063) e sono sovrascrivibili per run via params_override nel
POST /api/v1/pattern/runs (dal frontend: bottone "thresholds" del Pattern
Analyzer) o stabilmente aggiornando default_params con una migration.
Prefix list correnti (migration 0063)
premium_prefixes(wangiri, irsf):870(Inmarsat),881(GMSS),882/883(International Networks),979(International Premium Rate),900(legacy seed, premium nazionali instradati con quel prefisso). Lista E.164 senza+, match per prefisso sucdr.dst.msrn_prefixes(msrn_range): vuota by design — gli MSRN range sono specifici dell'operatore/roaming partner. La detection resta inerte finché la lista non viene configurata per il deployment.
Note di taratura su traffico reale
- Il traffico benchmark (SIPp, originator 1/6) satura
ping_callseconcentration_risk(score 100 clampato): è il comportamento atteso, non un falso positivo — su finestre di produzione escludere gli originator di test viascope.originator_idso flagis_test. min_samplessegue ADR-0027: alzare i valori se le finestre schedulate sono brevi (<15 min) per evitare findings su campioni esigui.- Le scheduled runs (TASK-538) usano finestre ≤24h: per baseline detections
(
irsf14d,temporal_anomaly28d) la baseline è comunque letta fuori finestra, nessuna taratura aggiuntiva richiesta.