Passa al contenuto principale

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

#PatternTrigger principale
1WangiriRing breve + callback verso premium
2IRSF (International Revenue Share Fraud)Volume anomalo verso destination premium pagate al terminator
3SIM BoxOriginator dichiarato internazionale ma A-number sequenziali da pool mobile locale
4Ping callsSpike CPS con duration <1s, ACD bassissima
5Concentration>X% traffico verso singolo prefisso/dest in finestra T
6TemporalVolume fuori distribuzione storica (ore notturne / weekend)
7CLI AnomaliCLI non in formato E.164 valido, lunghezze fuori range, all-zero
8MSRN leakMobile Station Roaming Number presenti in CDR di B-leg
9Call CenterPattern 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 rangeSeverityAzione default
0–29OKnessuna azione
30–59LOWlog + notify NOC Telegram
60–79MEDIUMthrottle CPS 50%, ticket auto-open
80–100HIGHblock 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 su cdr.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_calls e concentration_risk (score 100 clampato): è il comportamento atteso, non un falso positivo — su finestre di produzione escludere gli originator di test via scope.originator_ids o flag is_test.
  • min_samples segue 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 (irsf 14d, temporal_anomaly 28d) la baseline è comunque letta fuori finestra, nessuna taratura aggiuntiva richiesta.