È sicuro risolvere gli errori Access-Control-Allow-Origin (CORS origin) con una direttiva header PHP?

10 ott 2016, 20:21:14
Visualizzazioni: 23.9K
Voti: 5

Sto cercando di mostrare un form di Formidable Pro da un sito WordPress ad un altro. Ho seguito l'API dello sviluppatore e la REST API, ma ho riscontrato un problema CORS.

Poi ho trovato un suggerimento in una discussione del forum che suggeriva di aggiungere questa riga di codice nel file functions.php del sito dove si trova il form originale:

header("Access-Control-Allow-Origin: *");

Ho provato questo codice e ha funzionato perfettamente.

La mia domanda è: questo codice apre rischi di sicurezza o altre vulnerabilità?

La soluzione sembra troppo semplice per un problema che molte persone affrontano.

Il vostro contributo è molto apprezzato.

2
Commenti

@markratledge. Grazie per aver modificato la domanda. Ora ha più senso e sicuramente mi ha aiutato a scrivere domande migliori.

Atef Wagih Atef Wagih
12 ott 2016 07:29:34

Mi chiedo se questa risposta possa essere utile: https://wordpress.stackexchange.com/a/226494/51462

Ryan Ryan
13 ago 2017 05:02:57
Tutte le risposte alla domanda 2
6

Sì, stai aprendo il tuo sito a richieste AJAX da qualsiasi altro script su tutto il web.

Sarebbe meglio se limitassi l'origine a un dominio remoto specifico da cui stai consumando l'API, come questo esempio:

header("Access-Control-Allow-Origin: http://mozilla.com");

Tuttavia, come afferma la documentazione di mozilla, un client può falsificare l'origine, ma limitare i siti a cui un utente casuale può connettersi è un deterrente per alcuni attacchi.

Ancora meglio, puoi limitare le tue richieste solo ai metodi che hai davvero bisogno di consentire, l'essenza è questo snippet, e funziona per diversi domini, se hai la variabile $_SERVER['HTTP_ORIGIN'] popolata:

add_action('rest_api_init', function() {

     /* scollega la funzione predefinita */
     remove_filter('rest_pre_serve_request', 'rest_send_cors_headers');

     /* poi aggiungi il tuo filtro personalizzato */
     add_filter('rest_pre_serve_request', function( $value ) {
          $origin = get_http_origin();
          $my_sites = array( 'http://site1.org/', 'http://site2.net', );
          if ( in_array( $origin, $my_sites ) ) {
              header( 'Access-Control-Allow-Origin: ' . esc_url_raw( $origin ) );
          } else {
              header( 'Access-Control-Allow-Origin: ' . esc_url_raw( site_url() ) );
          }
          header( 'Access-Control-Allow-Methods: GET' );

          return $value;
     });
}, 15);

Come puoi vedere, questo snippet utilizza la funzione get_http_origin fornita da WordPress, ma restituirà null o vuoto, se la chiave HTTP_ORIGIN non è popolata nell'array $_SERVER, quindi non è disponibile per lo script PHP, forse perché è bloccata dal proxy cloudflare che stai utilizzando. Controlleresti velocemente, con uno script contenente <?php phpinfo(); ?>, se hai questa variabile popolata.

Forse l'origine del sito è popolata in un altro header da cloudflare, e potresti usarla in una funzione agganciata al filtro http_origin. Se sei perso a questo punto, modifica la tua domanda originale inserendo i contenuti della variabile _SERVER, escludendo i percorsi del filesystem o le password.

Sarei felice di aiutare.

11 ott 2016 20:17:24
Commenti

Grazie. La prima soluzione ha funzionato per me. Ma dato che ho 4 siti che voglio permettere di accedere al sito principale, devo ripetere la riga 4 volte cambiando l'URL del sito, oppure si può combinare in un unico comando? Grazie

Atef Wagih Atef Wagih
12 ott 2016 11:14:51

Certo che puoi, io di solito permetto l'accesso all'API solo a pochi siti, ho aggiornato la mia risposta con il controllo per questo, se funziona, potresti votare positivamente la risposta?

Jesús Franco Jesús Franco
12 ott 2016 20:25:13

la prima soluzione ha funzionato solo per 1 dominio. se ripeto la riga, non funziona. Ho provato il metodo in questo thread link, ma non funziona neanche. Quando applico la soluzione 2, questo è quello che ottengo: XMLHttpRequest cannot load https://coptic-treasures.com/wp-json/frm/v2/forms/6?return=html. The 'Access-Control-Allow-Origin' header has a value 'https://coptic-treasures.com' that is not equal to the supplied origin. Origin 'https://audio.coptic-treasures.com' is therefore not allowed access.

Atef Wagih Atef Wagih
14 ott 2016 11:39:24

Non puoi utilizzare l'header Allow Origin più di una volta. Ho aggiornato la mia risposta con ulteriori istruzioni per aiutarti a debuggare il problema, perché non dovrebbe sempre restituire lo stesso sito e dovrebbe riconoscere la lista dei tuoi domini che passi all'array. Per favore aggiorna la tua domanda con i dati della variabile $_SERVER, restituiti da phpinfo(), escludendo password e percorsi del filesystem. Sarò felice di aiutarti.

Jesús Franco Jesús Franco
14 ott 2016 21:24:53

Mi ci sono voluti circa 2 giorni per scoprire come rimuovere l'accesso CORS dall'API WP-JSON. Grazie per questo. Rimuovi la chiamata alla funzione rest_send_cors_headers!

dewd dewd
22 nov 2019 19:19:02

Se questo ti ha aiutato, potresti considerare di votare positivamente la risposta?

Jesús Franco Jesús Franco
22 nov 2019 21:10:52
Mostra i restanti 1 commenti
16

contesto - i browser limitano l'accesso remoto da script solo al sito da cui è stato caricato. Se questo tipo di controllo non venisse effettuato, mentre si visita un sito X sarebbe possibile per esso inviare dati al tuo account Gmail (se sei loggato) senza nemmeno dover indovinare nome utente e password, perché il browser avrebbe inviato i cookie di autenticazione corretti a Gmail.

Il "protocollo" CORS è lì per aiutarti a rilassare questa restrizione quando necessario.

Quindi la domanda che dovresti porti è: ne ho bisogno? Da un lato, non vedo perché il 99% dei siti WordPress dovrebbe averne bisogno, dall'altro i cookie di WordPress hanno una durata relativamente breve e il 99% dei siti WordPress non sarà un bersaglio di un tale attacco casuale.

Direi che, dato che l'API REST è mutabile e ha accesso a informazioni private, non dovresti usare l'API REST nella tua soluzione se devi abilitare CORS, è meglio scrivere la tua API "sola lettura".

11 ott 2016 21:21:33
Commenti

L'OP non sta parlando del 99% dei siti WP là fuori, ma dei propri siti, e secondo la domanda è necessario rendere disponibili risorse da altri siti.

Jesús Franco Jesús Franco
13 ott 2016 17:23:13

@JesúsFranco, e il tuo punto è?

Mark Kaplun Mark Kaplun
13 ott 2016 17:58:44

Che il punto è rispondere alla domanda, è l'obiettivo di questo sito.

Jesús Franco Jesús Franco
13 ott 2016 19:41:17

@JesúsFranco, penso che la mia reputazione dimostri che so come rispondere alle domande e non ho bisogno dei tuoi consigli?

Mark Kaplun Mark Kaplun
13 ott 2016 19:50:29

Quindi, hai un'idea specifica su come l'OP può risolvere questo problema?

Jesús Franco Jesús Franco
14 ott 2016 21:26:02

@JesúsFranco, l'OP ha chiesto se è sicuro. La risposta è che non lo è. La soluzione è ovviamente non fare cose che richiedono l'uso di cors

Mark Kaplun Mark Kaplun
15 ott 2016 01:13:43

La mia domanda si basa su ciò che affermi riguardo al rischio di accesso a informazioni private. In realtà, uno dei principi fondamentali dell'API è che solo lo sviluppatore può concedere l'accesso a informazioni private, poiché l'API così come fornita upstream non lo permette.

Jesús Franco Jesús Franco
15 ott 2016 20:16:30

@JesúsFranco Per quanto ne so, l'API utilizza i cookie per l'autenticazione e le persone con il ruolo di amministratore, ad esempio, possono ottenere quasi tutte le informazioni. Se disabiliti completamente il CORS e io utilizzo qualche forma di phishing per portarti sul mio sito, posso scrivere del JS che eseguirà qualsiasi operazione sul tuo sito, perché sei autenticato in esso e il tuo browser invierà semplicemente i cookie di autenticazione come parte della richiesta. Non avrò nemmeno bisogno di indovinare il tuo nome utente... Non è nemmeno sufficiente bloccare l'accesso agli endpoint di "scrittura" poiché come amministratore puoi ottenere informazioni riservate

Mark Kaplun Mark Kaplun
15 ott 2016 21:50:50

È possibile che attualmente non ci sia molto che possa essere ottenuto con l'API, ma il suo obiettivo è quello di poter sostituire l'intera amministrazione, quindi dovrà servire al client tutti i dati esistenti.

Mark Kaplun Mark Kaplun
15 ott 2016 21:52:10

Grazie Mark, conoscere il meccanismo che può essere abusato per trasformare l'accesso all'API in qualcosa di insicuro è molto utile per pensare a come gestire quei rischi, e quindi poter decidere se utilizzare una patch, limitare in altro modo gli utilizzi se i metodi utilizzabili dagli script remoti, o scrivere una nuova API da zero.

Jesús Franco Jesús Franco
16 ott 2016 19:43:11

@MarkKaplun Sono nuovo a WP-API quindi avevo una domanda. Consentire CORS solo per i metodi 'GET' esporrebbe comunque il server a vulnerabilità?

Shariq Hasan Khan Shariq Hasan Khan
26 ott 2018 17:41:24

@shariqkhan, probabilmente è meglio chiederlo su SO o su security stack, ma in generale la risposta è sì. CORS dovrebbe essere disabilitato solo per siti di cui ti fidi o su sottodomini tuoi che non eseguono alcuna azione senza che vengano inviate credenziali di autorizzazione nel corpo della richiesta. Finché l'API REST utilizza i cookie per l'autenticazione e viene eseguita sullo stesso dominio del sito WP, dovresti essere molto cauto nel disabilitarlo.

Mark Kaplun Mark Kaplun
27 ott 2018 07:47:11

ma ancora una volta, se disabiliti CORS solo per un URL specifico che sai non potrà essere utilizzato per fare danni, allora potrebbe essere OK. Non è tanto una questione di GET vs POST, ma di cosa viene effettivamente fatto su quel endpoint

Mark Kaplun Mark Kaplun
27 ott 2018 07:50:42

Grazie @MarkKaplun, ho visto le tue molte risposte su SO/SE quindi so che sai di cosa parli, probabilmente lo chiederò su SO, anche se sento che la domanda potrebbe essere chiusa come 'troppo ampia' o come 'duplicato'. Sono incuriosito da come vari siti web come Github, Twitter (e molti siti basati su WordPress) aprono le loro API disabilitando le restrizioni CORS per tutti. Ero dell'idea che se disabiliti CORS solo per le richieste GET, sia abbastanza innocuo perché stai solo permettendo ad altri di recuperare dati e non modificare nulla?

Shariq Hasan Khan Shariq Hasan Khan
28 ott 2018 08:16:10

La differenza tra wordpress e altri siti è che non usano autenticazione basata su cookie per l'API, e l'utilizzo dell'API richiede l'invio di informazioni di tipo utente e password esplicitamente in ogni richiesta. L'API di WordPress <rant alert> è stata progettata male in quel senso, e probabilmente non poteva essere progettata meglio dato che doveva supportare comunicazioni non sicure su HTTP che impedivano di utilizzare la tecnica utente/password poiché chiunque in ascolto su una (ad esempio) WiFi avrebbe scoperto i valori.

Mark Kaplun Mark Kaplun
29 ott 2018 04:40:33

il fatto che i cookie siano impostati quando sei loggato è ciò che gli attaccanti possono sfruttare per inviare richieste AJAX come se fossero originate da te. Con il CORS attivo, queste richieste falliranno per altri domini, e poiché sei l'unico che controlla il dominio sei al sicuro. Più siti per cui disabiliti il CORS, più posti un attaccante può controllare e attaccarti convincendoti a visitare quel sito. La domanda riguardava la disattivazione completa del CORS per tutti i siti, che è molto pericolosa, ma se lo disabiliti per altri domini che controlli completamente, pur non essendo una grande cosa, non è così grave.

Mark Kaplun Mark Kaplun
29 ott 2018 04:46:52
Mostra i restanti 11 commenti