Un controllo adattivo diventa verificabile quando ogni decisione ha ingressi definiti, un esito esplicito e un punto preciso in cui l’operazione viene eseguita o sospesa. Il punteggio comportamentale è soltanto uno degli ingressi: non deve trasformarsi in un permesso implicito.
Il seguente pseudocodice descrive una possibile realizzazione sperimentale dell’analisi spettrale del comportamento. Non è un programma pronto per la produzione. Le funzioni di autenticazione, persistenza ed esecuzione indicano contratti che un’implementazione deve soddisfare e verificare con prove specifiche. Non sono riportati risultati di efficacia.
Definire dati, configurazione ed esiti
Il servizio usa eventi raccolti lato server: istante, categoria dell’operazione e identificatore della sessione. Le finestre comprendono soltanto eventi precedenti alla richiesta valutata. I dati del client, se presenti, restano segnali non attendibili finché non intervengono controlli adeguati.
La configurazione stabilisce durata dei campioni, numero di campioni, canali, frequenze e coppie di canali da confrontare. Stabilisce anche quali caratteristiche siano indispensabili. Schema, trasformazioni e normalizzazione devono coincidere tra addestramento e valutazione.
CONFIGURAZIONE VERSIONATA
N, intervallo, canali
frequenze_selezionate, coppie_canali
soglie_ampiezza, schema_caratteristiche
copertura_minima, caratteristiche_obbligatorie
regole_operazioni, scadenza_verifica, limite_tentativi
PROFILO PER UTENTE E CONTESTO
versione, versione_schema, periodo_addestramento
media[j], deviazione[j], minimo_scala[j], peso[j]
maschere_validate, soglie_per_maschera
ESITI DEL VALUTATORE
COMPATIBILE, ANOMALO, INSUFFICIENTE, ERRORE
ESITI DEL CONTROLLO
NEGATO, VERIFICA_RICHIESTA, SOSPESO, ESEGUITO
Nessuna soglia numerica è universale. I valori devono essere scelti con dati separati da quelli della prova finale. Un nuovo utente, uno schema incompatibile o una raccolta incompleta producono un esito esplicito, mai un punteggio zero usato come sinonimo di normalità.
Estrarre ampiezze e relazioni di fase
Ogni canale è una sequenza reale di conteggi in intervalli regolari. La funzione RFFT calcola le componenti non ridondanti della trasformata per dati reali. Per rendere l’esempio riproducibile, adottiamo la trasformata diretta non normalizzata, senza sottrarre la media e senza applicare una finestra di pesatura.
Il conteggio totale viene conservato separatamente. Le frequenze selezionate escludono la componente continua k = 0. L’eventuale componente di Nyquist richiede la stessa convenzione nell’addestramento e nella valutazione. Le ampiezze vengono trasformate con log1p, cioè log(1 + A), per attenuare la scala dei valori elevati; questa è una scelta del modello da confrontare con alternative.
FUNZIONE estrai(finestra, cfg):
SE raccolta_incompleta(finestra):
RITORNA INSUFFICIENTE
SE NON conteggi_validi_e_finiti(finestra):
RITORNA ERRORE
v = mappa_vuota()
PER c IN cfg.canali:
x = conta_eventi(finestra, c, cfg.N, cfg.intervallo)
X[c] = RFFT(x, normalizzazione="diretta_non_scalata")
v["totale", c] = somma(x)
PER k IN cfg.frequenze_selezionate:
v["ampiezza", c, k] = log1p(modulo(X[c][k]))
PER (a, b) IN cfg.coppie_canali:
PER k IN cfg.frequenze_selezionate:
SE modulo(X[a][k]) <= cfg.soglia(a, k): CONTINUA
SE modulo(X[b][k]) <= cfg.soglia(b, k): CONTINUA
fase = argomento(X[a][k] * coniugato(X[b][k]))
v["fase_cos", a, b, k] = cos(fase)
v["fase_sin", a, b, k] = sin(fase)
SE NON tutti_finiti(v): RITORNA ERRORE
RITORNA CARATTERISTICHE(v, chiavi(v), cfg.versione)
Una fase esclusa resta assente dalla maschera delle caratteristiche. Non viene sostituita con zero, che rappresenterebbe un valore specifico. Un comportamento con poche componenti misurabili deve quindi essere trattato secondo una politica di copertura, non confrontato come se contenesse tutte le informazioni.
Calcolare uno scostamento senza inventare probabilità
Il confronto usa la distanza standardizzata:
dj = (vj − μj) / max(σj, εj)
S = (Σj∈J wjdj2) / (Σj∈J wj)
J identifica le caratteristiche disponibili. I pesi e i minimi di scala sono positivi; la deviazione standard può essere nulla. L’esempio ammette soltanto maschere già validate: una combinazione nuova di dati mancanti richiede verifica aggiuntiva, anziché una soglia improvvisata.
FUNZIONE valuta(caratteristiche, profilo, cfg):
SE caratteristiche è ERRORE: RITORNA ERRORE
SE caratteristiche è INSUFFICIENTE: RITORNA INSUFFICIENTE
SE profilo assente: RITORNA INSUFFICIENTE
SE schema_incompatibile(caratteristiche, profilo, cfg):
RITORNA INSUFFICIENTE
SE NON parametri_profilo_validi(profilo): RITORNA ERRORE
J = caratteristiche.maschera
SE NON copertura_adeguata(J, cfg): RITORNA INSUFFICIENTE
SE J NON IN profilo.maschere_validate: RITORNA INSUFFICIENTE
numeratore = 0
denominatore = 0
PER j IN J:
scala = max(profilo.deviazione[j], profilo.minimo_scala[j])
d = (caratteristiche.v[j] - profilo.media[j]) / scala
numeratore += profilo.peso[j] * d * d
denominatore += profilo.peso[j]
S = numeratore / denominatore
SE NON finito(S): RITORNA ERRORE
SE S > profilo.soglie_per_maschera[J]: RITORNA ANOMALO
RITORNA COMPATIBILE
Il punteggio non è una percentuale di rischio. Anche una distanza piccola può appartenere a una sessione sottratta o imitata. Punteggio, maschera e versione possono essere registrati nei log riservati per la valutazione, mentre l’interfaccia pubblica riceve soltanto l’esito operativo necessario.
Decidere prima di eseguire
Il controllo riceve una richiesta, ne valida i parametri e costruisce sul server un’operazione canonica. Identità, contesto e sensibilità non vengono accettati come dichiarazioni affidabili del browser.
Nel percorso mostrato, qualsiasi operazione classificata come sensibile richiede una verifica se il comportamento non è compatibile. Le operazioni che impongono sempre una conferma mantengono questa regola. Per quelle non sensibili restano attivi i controlli ordinari: questa scelta limita deliberatamente il perimetro della protezione adattiva.
FUNZIONE gestisci(richiesta):
sessione = autentica_sessione(richiesta)
SE sessione non valida: RITORNA NEGATO
SE limite_richieste_superato(sessione): RITORNA NEGATO
op = valida_e_canonicalizza(richiesta, sessione)
SE op non valida: RITORNA NEGATO
SE NON autorizzato(sessione, op): RITORNA NEGATO
regola = politica_corrente(op, sessione)
SE regola assente: RITORNA NEGATO
esito = analisi_con_timeout(sessione, op.contesto)
# Timeout ed eccezioni producono ERRORE.
verifica = regola.conferma_sempre
SE regola.sensibile E esito != COMPATIBILE:
verifica = VERO
SE verifica:
SE NON fattore_adeguato_disponibile(sessione, regola):
RITORNA SOSPESO
ticket = crea_verifica_server(sessione, op, regola)
RITORNA VERIFICA_RICHIESTA(ticket.id, riepilogo(op))
RITORNA esegui_controllata(sessione, op, prova=ASSENTE)
La funzione di analisi applica un tempo massimo e converte gli errori in un esito definito. Nessuna eccezione può saltare direttamente all’esecuzione. Per evitare che richieste ripetute provochino notifiche continue, la creazione delle verifiche applica limiti e riusa una verifica pendente soltanto per la stessa sessione e la stessa operazione immutabile.
Vincolare la conferma alla richiesta sospesa
Un ticket conserva sul server utente, sessione, parametri canonici dell’operazione, risorsa e versione rilevante, scadenza, tentativi e requisito di autenticazione. Il suo identificatore è imprevedibile, ma non costituisce da solo un’autorizzazione.
La prova viene validata da una libreria di autenticazione appropriata al fattore registrato. Per esempio, la verifica di una passkey comprende i controlli previsti dal relativo protocollo. Un codice temporaneo richiede limiti ai tentativi e protezione dal riutilizzo; non offre automaticamente la stessa resistenza al phishing. La schermata di conferma mostra i dati significativi dell’operazione conservata sul server.
FUNZIONE conferma(richiesta, ticket_id, risposta_fattore):
sessione = autentica_sessione(richiesta)
SE sessione non valida: RITORNA NEGATO
ticket = carica_ticket_riservato(ticket_id)
SE ticket assente: RITORNA NEGATO
SE NON appartiene(ticket, sessione): RITORNA NEGATO
SE scaduto_o_chiuso(ticket): RITORNA NEGATO
SE NON prenota_tentativo_atomicamente(ticket): RITORNA NEGATO
prova = verifica_fattore_registrato(
sessione.utente, risposta_fattore, ticket)
SE prova non valida: RITORNA NEGATO
# La prova è un oggetto interno, non un booleano del client.
RITORNA esegui_controllata(sessione, ticket.operazione, prova)
Il browser non può sostituire la destinazione o i parametri dell’operazione durante la conferma. Se l’utente li modifica, serve una nuova richiesta. La riuscita dell’autenticazione non assegna privilegi aggiuntivi.
Il contratto dell’esecuzione controllata
La funzione finale è il confine operativo del modello. Deve ricontrollare sessione, permessi, politica corrente e stato della risorsa nel momento in cui applica l’azione. Deve inoltre rifiutare una prova scaduta, già consumata, destinata a un’altra operazione o non più sufficiente secondo la politica corrente.
FUNZIONE esegui_controllata(sessione, op, prova):
IN TRANSAZIONE O MECCANISMO EQUIVALENTE:
ricontrolla_sessione_e_permessi(sessione, op)
verifica_versione_e_precondizioni(op)
requisito = requisito_corrente(sessione, op)
SE requisito impone verifica:
valida_prova_interna(prova, sessione, op, requisito)
consuma_prova_una_sola_volta(prova)
applica_o_accoda_una_sola_volta(op)
registra_esito_minimo(op)
RITORNA ESEGUITO_O_ACCETTATO
Questa notazione esprime un requisito da implementare, non una garanzia prodotta dalla parola «transazione». Se l’effetto avviene nello stesso database, controlli, consumo della prova e modifica possono condividere la transazione. Per un servizio esterno occorrono una coda persistente e operazioni idempotenti, capaci di gestire ritentativi senza duplicare gli effetti.
Il risultato «accettato» indica soltanto che l’operazione è stata accodata; «eseguito» richiede conferma dell’effetto. Se il sistema esterno non permette un’idempotenza affidabile, resta necessaria una procedura di riconciliazione. La chiave dell’operazione viene associata dal server a utente e parametri: non si riutilizza per azioni differenti.
Il requisito corrente conserva l’eventuale obbligo di verifica già deciso per la richiesta pendente, può rafforzarlo e può negare l’azione. Non lo annulla perché, nel frattempo, una finestra comportamentale diversa appare normale.
Aggiornare il profilo in un percorso separato
La finestra appena valutata non modifica subito il riferimento. Un processo separato raccoglie campioni candidati soltanto con evidenze di autenticazione e provenienza adeguate; il solo esito COMPATIBILE non basta a renderli attendibili.
FUNZIONE prepara_aggiornamento(candidati, profilo_attivo):
dati = filtra_provenienza_qualita_e_verifiche(candidati)
dati = limita_contributo_per_sessione_e_periodo(dati)
SE dati insufficienti: RITORNA NESSUNA_MODIFICA
candidato = stima_profilo_con_schema_fissato(dati)
calibra_soglie(candidato, insieme_calibrazione_separato)
rapporto = confronta_con_attivo(candidato, dati_di_controllo)
SE NON soddisfa_criteri_prefissati(rapporto):
RITORNA NESSUNA_MODIFICA
pubblica_versione_atomica(candidato, conservando=profilo_attivo)
Il confronto di promozione valuta falsi allarmi, verifiche aggiuntive, copertura e scenari ostili disponibili. I dati di controllo non sostituiscono una prova finale indipendente e non devono essere riutilizzati indefinitamente per ottimizzare il modello. La versione precedente resta disponibile per il ripristino.
Verifiche prima di un prototipo operativo
I casi seguenti sono criteri di prova proposti, non test già eseguiti:
- Permessi assenti e punteggio basso: nessuna esecuzione.
- Profilo assente, dati incompleti o errore del valutatore: verifica per una richiesta sensibile, mai autorizzazione automatica.
- Fase con modulo insufficiente: caratteristica assente; maschera non validata: esito INSUFFICIENTE.
- Parametro modificato dopo la conferma, ticket scaduto o sessione revocata: nessuna esecuzione.
- Due conferme concorrenti dello stesso ticket: al massimo un effetto dell’operazione.
- Arresto tra conferma e risposta, seguito da ritentativo: recupero dell’esito senza duplicazione.
- Campione soltanto compatibile ma senza verifiche adeguate: esclusione dall’aggiornamento automatico.
La valutazione dell’utilità richiede poi sessioni separate per addestramento, calibrazione e prova, con un confronto tra regole ordinarie, ampiezze e ampiezze con fase relativa. Il risultato da cercare è un miglioramento misurabile nel rapporto tra operazioni illecite fermate e disturbo imposto agli utenti legittimi. La descrizione del flusso rende controllabili le scelte; l’efficacia deve ancora essere dimostrata.