Come funziona Google reCAPTCHA Enterprise
Google ha reso disponibile un nuovo tool per la sicurezza delle applicazioni web: reCAPTCHA Enterprise.
Le precedenti versioni basate sulle sfide CAPTCHA (il click su un checkbox o la scelta di determinate immagini) sono ormai superate e hanno alcune implicazioni da tenere in considerazione nel caso in cui si vogliano ancora utilizzare:
- richiedono un'interazione dell'utente, diminuendo potenzialmente i tassi di conversione (ogni azione aggiuntiva richiesta a un utente lo "rallenta")
- l'intelligenza artificiale è molto avanzata e può ormai facilmente risolvere tali sfide, rendendo difficile distinguere persone e bot
- i "vecchi" CAPTCHA non sono accessibili per tutti i tipi di utenti e potrebbero anche in questo caso ridurre i tassi di conversione (oltre a non essere adatti nel caso in cui un sito preveda requisiti di accessibilità)
Entra quindi in gioco la nuova versione Enterprise, che permette di eseguire un controllo senza un'interazione diretta dell'utente e restituisce invece un punteggio che la nostra applicazione può andare a interpretare per valutare se abilitare una determinata azione da parte di un utente, bloccarla o richiedere metodi alternativi di verifica (ad esempio tramite two factor auth).
Ma come funziona?
La documentazione riporta questo schema, che ho diviso in due parti per maggior chiarezza:
SEZIONE 1 - BLUE
La prima sezione è relativa alle interazioni lato utente, eseguite nel browser tramite javascript.
I passaggi sono i seguenti:
- l'utente apre una pagina che deve essere "protetta", quindi ad esempio una pagina di login, pagamento o un form contatti
- viene caricata la libreria da Google e viene generato un token univoco per l'azione corrente
In questo esempio di codice semplificato il token viene richiesto al caricamento della pagina (ma si può richiedere in seguito a un'azione specifica, ad esempio al click su un pulsante prima di inviare un form).
Nell'header andiamo ad aggiungere:
<script src="https://www.google.com/recaptcha/enterprise.js?render=<?php echo GC_KEY;?>"></script>
<script>
//al caricamento della libreria
grecaptcha.enterprise.ready(function() {
//richiedo il token
grecaptcha.enterprise.execute('xxxxxxxxxxxxx', {action: 'login'}).then(function(token) {
//imposto il token e l'azione in due input del form che poi andrò a inviare
document.getElementById('cgtkn').value = token;
document.getElementById('cgtkn_act').value = 'login';
});
});
</script>
In questo modo ricavo il token univoco che mi servirà nella fase successiva e lo associo a un campo nascosto del form.
Allo stesso modo imposto un campo nascosto con il nome dell'azione (ad esempio "login", ma può essere qualsiasi nome).
SEZIONE 2 - ROSSO
Questo è il momento da cui inizia il vero controllo.
Immaginiamo che l'utente abbia ora inviato al server i dati del form di login (che contiene anche i valori relativi al token e all'azione), tramite POST o Ajax è indifferente.
Il server, prima di autorizzare il login, contatterà il servizio recaptcha enterprise inviando il token e il nome dell'azione.
Il servizio restituirà quindi un json, indicando se il token è valido e un punteggio che indica il grado di affidabilità dell'interazione.
Il punteggio va da 0.1 (scarsa affidabilità) a 1.0 (affidabilità alta).
E' possibile utilizzare le librerie a disposizione per i vari linguaggi di programmazione oppure tramite l'API REST.
Con PHP possiamo utilizzare la libreria cURL per comunicare con l'api senza dipendere da librerie esterne, ecco un esempio di codice (per semplificare non ci sono controlli):
//ricavo i dati dal form
$token = $_POST['token'];
$action = $_POST['action'];
//url dell'API
$url = 'https://recaptchaenterprise.googleapis.com/v1/projects/' . GOOGLE_PROJECT_ID . '/assessments?key=' . GOOGLE_API_KEY;
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
//payload
$data = ['event' => ['token' => $token, 'siteKey' => GC_KEY, 'expectedAction' => $action]];
//invio payload: in formato json
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type:application/json'));
$resp = curl_exec($ch);
curl_close($ch);
//anche la risposta è in formato json, posso decodificarla
$decoded_resp = json_decode($resp, TRUE);
La risposta, che è in formato json, è formattata in questo modo:
{
"tokenProperties": {
"valid": true,
"hostname": "www.google.com",
"action": "homepage",
"createTime": "2019-03-28T12:24:17.894Z"
},
"riskAnalysis": {
"score": 0.1,
"reasons": ["AUTOMATION"]
},
"event": {
"token": "TOKEN",
"siteKey": "KEY",
"expectedAction": "USER_ACTION"
},
"name": "projects/PROJECT_NUMBER/assessments/b6ac310000000000"
}
Da qui possiamo fare i diversi controlli per valutare come procedere; principalmente andrebbero eseguiti 3 controlli in sequenza:
//controllo se il token è valido - TRUE/FALSE
$decoded_resp['tokenProperties']['valid']
//controllo che l'azione corrisponda
$decoded_resp['tokenProperties']['action'] == $decoded_resp['event']['expectedAction']
//controllo lo score 0.1-1.0 -> in base al punteggio decido come procedere
$decoded_resp['riskAnalysis']['score']
I primi due indicano subito la validità della richiesta e se falliscono significa che c'è qualche problema.
Il terzo controllo sullo score è quello che va invece valutato.
Come detto può avere un valore da 0.1 a 1.0, e più il punteggio è alto più è probabile che la richiesta sia legittima e non eseguita da un bot o programma maligno.
Sugli 11 livelli, per impostazione predefinita sono disponibili solo i seguenti 4 livelli: 0,1, 0,3, 0,7 e 0,9 (è possibile richiedere lo sblocco di tutti i livelli al team di vendita Google).
Il nostro software quindi potrà a questo punto decidere cosa fare in base al punteggio, ad esempio:
- 0.9: l'azione è legittima e quindi procedo (con il login, pagamento, invio form, ....)
- 0.7: richiedo all'utente un controllo aggiuntivo (esempio: invio un codice via mail)
- 0.3 / 0.1: la richiesta è probabilmente illegittima; eseguo un controllo maggiore o blocco la richiesta

Commenti