La REST API di WordPress gestisce l’autenticazione in modo leggermente diverso rispetto alla sua autenticazione standard basata sul login.
Supporta non solo l’autenticazione basata su cookie, ma anche password applicative e OAuth .
Gli endpoint REST API personalizzati vengono registrati tramite la funzione register_rest_route().
Autenticazione basata su cookie: quando un utente effettua l’accesso, le richieste API REST possono essere autenticate tramite gli stessi cookie utilizzati per le normali operazioni di WordPress.
Ciò significa che una route REST registrata (ad esempio, http://example-wordpress-site.com/wp-json/{rest_route}) è accessibile allo stesso modo di qualsiasi altra route.
Tuttavia, se non viene fornito un valore valido per X-WP-Nonce nella richiesta, WordPress considererà la richiesta non autenticata, nonostante i cookie di autenticazione forniti siano validi.
Questo perché l’implementazione dell’API REST di WordPress ha una protezione integrata contro la falsificazione delle richieste tra siti (CSRF).
Il controllo con X-WP-Nonce è automatico e rilevante solo per l’autenticazione basata sui cookie.
💡 Se un utente che ha effettuato l’accesso con il ruolo di amministratore invia una richiesta a un endpoint API REST e la richiesta non contiene un valore valido per X-WP-Nonce, la richiesta verrà considerata come proveniente dall’ID utente 0, ovvero non autenticata.
Password delle applicazioni: introdotte in WordPress 5.6, le password delle applicazioni consentono agli utenti di creare password univoche per le applicazioni esterne che accedono al sito tramite API REST.
Questo metodo non richiede la creazione di un account utente e la condivisione della password.
OAuth: OAuth può essere implementato per fornire un’autenticazione sicura basata su token per determinate applicazioni o integrazioni di terze parti.
Ogni endpoint REST API registrato ha un metodo di richiesta (ad esempio GET, POST, ecc.), una funzione di callback (la logica che determina come gestire la richiesta a questo endpoint) e un callback di autorizzazione (ad esempio permission_callback()) che dovrebbe restituire true o false in base alla logica di autorizzazione definita dallo sviluppatore.
Le vulnerabilità nelle funzioni di callback dell’API REST derivano solitamente dalla mancanza di autorizzazione (ad esempio, la callback di autorizzazione del percorso restituisce true e la funzione di callback stessa non esegue un controllo di autorizzazione).
register_rest_route( 'myplugin/v1', '/delete-users', array(
'methods' => 'GET',
'callback' => 'delete_users_function',
'permission_callback' => '__return_true',
) );Una richiesta GET non autenticata http://example-wordpress-site.com/wp-json/myplugin/v1/delete-users eliminerà tutti gli utenti.
register_rest_route( 'myplugin/v1', '/delete-users', array(
'methods' => 'GET',
'callback' => 'delete_users_function',
'permission_callback' => function () {
return current_user_can( 'manage_options' );
},
) );Una richiesta GET a http://example-wordpress-site.com/wp-json/myplugin/v1/delete-users verrà negata fino a che il cookie fornito e il valore X-WP-Nonce non provenga da un utente che ha la capacità manage_options necessaria.
Gli sviluppatori possono anche implementare un proprio meccanismo di autorizzazione personalizzato per le route delle API REST, che dovrebbe essere attentamente esaminato per individuare potenziali aggiramenti.
Ecco un esempio di un controllo di autorizzazione mal implementato che è stato facilmente aggirato.
Logica del flusso di autenticazione e autorizzazione dell’API REST
REST API Request
│
├── Using Application Password, OAuth, or Basic Auth?
│ └── Yes → Authenticated User (based on credentials)
│
├── Using Cookies?
│ └── Yes → Is X-WP-Nonce valid?
│ ├── No → User ID 0 (unauthenticated)
│ └── Yes → Authenticated User (from cookie)
│
└── None of the above? → User ID 0 (unauthenticated)
│
Check permission_callback
│
├── Does permission_callback exist?
│ ├── No → ❌ Public endpoint (allow everyone)
│ │
│ └── Yes → Execute permission_callback()
│ │
│ ├── Does it perform a capability check?
│ │ ├── Yes (e.g., current_user_can())
│ │ │ ├── Pass → ✅ Allow access
│ │ │ └── Fail → ❌ Deny access (401/403)
│ │
│ │ └── No (returns true unconditionally)
│ │ → ✅ Public endpoint (allow everyone)
│
└── Proceed to callback function if allowed
Lascia un commento
Devi essere connesso per inviare un commento.