Este sigur să rezolvi erorile Access-Control-Allow-Origin (CORS origin) cu o directivă header PHP?

10 oct. 2016, 20:21:14
Vizualizări: 23.9K
Voturi: 5

Încerc să afișez un formular Formidable Pro de pe un site WordPress pe un alt site. Am urmat documentația dezvoltatorului și REST API, dar m-am confruntat cu o problemă CORS.

Apoi am găsit o sugestie într-un thread pe forum care propunea adăugarea acestei linii de cod în functions.php al site-ului unde se află formularul original:

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

Am încercat acest cod și a funcționat perfect.

Întrebarea mea este: acest cod creează riscuri de securitate sau alte vulnerabilități?

Soluția pare prea simplă pentru o problemă cu care se confruntă mulți oameni.

Apreciez foarte mult părerea voastră.

2
Comentarii

@markratledge. Mulțumesc pentru editarea întrebării. Acum are mai mult sens și cu siguranță m-a ajutat să formulez întrebări mai bune.

Atef Wagih Atef Wagih
12 oct. 2016 07:29:34

Mă întreb dacă acest răspuns ajută: https://wordpress.stackexchange.com/a/226494/51462

Ryan Ryan
13 aug. 2017 05:02:57
Toate răspunsurile la întrebare 2
6

Da, deschizi site-ul tău pentru a fi accesat prin AJAX de către orice alt script de pe întregul internet.

Ar fi mai bine să limitezi originea la un singur domeniu specific de la care consumi API-ul, ca în acest exemplu:

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

Totuși, după cum menționează documentația Mozilla, un client poate falsifica originea, dar limitarea site-urilor la care un utilizator obișnuit se poate conecta reprezintă un obstacol pentru unele atacuri.

Și mai bine, poți limita cererile doar la metodele pe care chiar trebuie să le permiți, esența este acest fragment de cod, care funcționează pentru mai multe domenii, dacă variabila $_SERVER['HTTP_ORIGIN'] este populată:

add_action('rest_api_init', function() {

     /* dezactivează funcția implicită */
     remove_filter('rest_pre_serve_request', 'rest_send_cors_headers');

     /* adaugă propriul filtru */
     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);

După cum poți vedea, acest fragment utilizează funcția get_http_origin oferită de WordPress, dar va returna null sau gol dacă cheia HTTP_ORIGIN nu este populată în array-ul $_SERVER, deci nu este disponibilă scriptului PHP, poate pentru că este blocată de proxy-ul Cloudflare pe care îl folosești. Aș verifica rapid, cu un script care conține <?php phpinfo(); ?>, dacă această variabilă este populată.

Poate că site-ul de origine este populat într-un alt header de către Cloudflare și ai putea să-l folosești într-o funcție conectată la filtrul http_origin. Dacă ești blocat până în acest punct, editează întrebarea inițială postând conținutul variabilei _SERVER, cu excepția câmpurilor ce conțin parole sau căi de sistem.

Aș fi bucuros să te ajut.

11 oct. 2016 20:17:24
Comentarii

Mulțumesc. Prima soluție a funcționat pentru mine. Dar având în vedere că am 4 site-uri pe care vreau să le permit accesul la site-ul principal, trebuie să repet linia de 4 ori și să schimb URL-ul site-ului, sau pot fi combinate într-o singură comandă? Mulțumesc.

Atef Wagih Atef Wagih
12 oct. 2016 11:14:51

Bineînțeles că poți, eu obișnuiesc să permit accesul la API doar pentru câteva site-uri. Am actualizat răspunsul meu cu verificarea pentru acest lucru. Dacă funcționează, ai putea să votezi răspunsul?

Jesús Franco Jesús Franco
12 oct. 2016 20:25:13

prima soluție a funcționat doar pentru 1 domeniu. dacă am repetat linia, nu a funcționat. Am încercat metoda din acest thread link, dar nu a funcționat nici aceea. Când am aplicat soluția 2, iată ce am primit: 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 oct. 2016 11:39:24

Nu poți folosi header-ul Allow Origin de mai multe ori. Am actualizat răspunsul meu cu instrucțiuni suplimentare pentru a te ajuta să depanezi problema, deoarece returnarea mereu a aceluiași site nu ar trebui să se întâmple și ar trebui să recunoască lista de domenii pe care o transmiți în array. Te rog să actualizezi întrebarea ta cu datele din variabila $_SERVER, returnate de phpinfo(), excluzând parolele și căile de sistem de fișiere. Aș fi bucuros să te ajut.

Jesús Franco Jesús Franco
14 oct. 2016 21:24:53

Mi-a luat cam 2 zile să aflu cum să elimin accesul CORS din API-ul WP-JSON. Mulțumesc pentru asta. Elimină apelul funcției rest_send_cors_headers!

dewd dewd
22 nov. 2019 19:19:02

Dacă acest răspuns te-a ajutat, ai putea să îi dai un vot pozitiv?

Jesús Franco Jesús Franco
22 nov. 2019 21:10:52
Arată celelalte 1 comentarii
16

context - browserele restricționează accesul la distanță din scripturi doar pentru site-ul de pe care a fost încărcat. Dacă acest tip de verificare nu ar fi făcut, în timp ce vizitați un site X, ar fi posibil ca acesta să trimită date în contul dvs. Gmail (dacă sunteți conectat) fără să fie nevoie să ghicească numele de utilizator și parola, deoarece browserul ar fi trimis cookie-urile corespunzătoare de autentificare către Gmail.

Protocolul CORS este conceput să vă ajute să relaxați această restricție atunci când este necesar.

Deci întrebarea pe care ar trebui să v-o puneți este: am nevoie de asta? Pe de o parte, nu văd de ce 99% dintre site-urile WordPress ar avea nevoie de această funcționalitate, pe de altă parte, cookie-urile WordPress au o durată de viață relativ scurtă și 99% dintre site-urile WordPress nu vor fi ținte pentru un astfel de atac aleatoriu.

Aș spune că, deoarece REST API este unul care permite modificări și are acces la informații private, nu ar trebui să utilizați REST API în soluția dvs. dacă trebuie să activați CORS, este mai bine să vă creați propriul API "doar pentru citire".

11 oct. 2016 21:21:33
Comentarii

OP nu vorbește despre 99% dintre site-urile WP existente, ci despre propriile site-uri, iar conform întrebării, este necesar să se facă disponibile resurse de pe alt site.

Jesús Franco Jesús Franco
13 oct. 2016 17:23:13

@JesúsFranco, și care este ideea ta?

Mark Kaplun Mark Kaplun
13 oct. 2016 17:58:44

Că ideea este să răspunzi la întrebare, acesta este scopul acestui site.

Jesús Franco Jesús Franco
13 oct. 2016 19:41:17

@JesúsFranco, cred că reputația mea arată că știu cum să răspund la întrebări și nu am nevoie de sfaturile tale?

Mark Kaplun Mark Kaplun
13 oct. 2016 19:50:29

Deci, ai o idee anume despre cum OP poate rezolva această problemă?

Jesús Franco Jesús Franco
14 oct. 2016 21:26:02

@JesúsFranco, OP a întrebat dacă este sigur. Răspunsul este că nu este. Soluția evidentă este să nu faci lucruri care să necesite utilizarea CORS

Mark Kaplun Mark Kaplun
15 oct. 2016 01:13:43

Întrebarea mea se bazează pe faptul că menționați că există un risc de acces la informații private. De fapt, unul dintre principiile de bază ale API-ului este că doar dezvoltatorul poate acorda acces la informații private, deoarece API-ul în forma sa originală nu oferă acest lucru.

Jesús Franco Jesús Franco
15 oct. 2016 20:16:30

@JesúsFranco Din câte știu eu, API-ul folosește cookie-uri pentru autentificare și persoanele cu rol de admin, de exemplu, pot obține aproape orice informație. Dacă CORS este complet dezactivat și eu folosesc un fel de phishing pentru a vă atrage pe site-ul meu, pot scrie un cod JS care va executa orice operație pe site-ul dumneavoastră, deoarece sunteți autentificat în el iar browserul dumneavoastră va trimite cookie-urile de autentificare ca parte a cererii. Nici măcar nu va trebui să ghicesc numele de utilizator... Nu este suficient nici măcar să blochezi accesul la punctele finale de "scriere", deoarece ca admin poți obține informații clasificate.

Mark Kaplun Mark Kaplun
15 oct. 2016 21:50:50

Este posibil ca în prezent să nu fie multe lucruri care pot fi obținute cu API-ul, dar scopul său este să poată înlocui întreaga interfață de administrare, așa că va trebui să servească clientului toate datele existente.

Mark Kaplun Mark Kaplun
15 oct. 2016 21:52:10

Mulțumesc Mark, cunoașterea mecanismului care poate fi abuzat pentru a transforma accesul la API în ceva nesigur, este foarte utilă pentru a gândi cum să gestionăm acele riscuri, iar apoi pentru a putea decide dacă poate fi folosit un patch, limitând în alte moduri utilizările metodelor disponibile pentru scripturile la distanță, sau pentru a scrie un API complet nou.

Jesús Franco Jesús Franco
16 oct. 2016 19:43:11

@MarkKaplun Sunt nou în WP-API, așa că am o întrebare. Permiterea CORS doar pentru metodele 'GET' ar expune și serverul la vulnerabilități?

Shariq Hasan Khan Shariq Hasan Khan
26 oct. 2018 17:41:24

@shariqkhan, aceasta este probabil mai bine întrebată pe SO sau pe stack-ul de securitate, dar în general, răspunsul este da. CORS ar trebui dezactivat doar pentru site-uri în care aveți încredere sau pe subdomenii ale dvs. care nu efectuează nicio acțiune fără a trimite credențiale de autorizare în corpul cererii. Atâta timp cât restul API-ului folosește cookie-uri pentru autentificare și rulează pe același domeniu ca site-ul WP, ar trebui să fiți foarte atenți cu dezactivarea acestuia.

Mark Kaplun Mark Kaplun
27 oct. 2018 07:47:11

dar din nou, dacă dezactivezi CORS doar pentru un URL specific despre care știi că nu poate fi folosit pentru a face vreun rău, atunci ar putea fi OK. Nu este atât de mult o problemă de GET vs POST, ci mai degrabă despre ce se întâmplă de fapt la acel endpoint

Mark Kaplun Mark Kaplun
27 oct. 2018 07:50:42

Mulțumesc @MarkKaplun, am văzut multe dintre răspunsurile tale pe SO/SE așa că știu că știi despre ce vorbești, probabil voi întreba pe SO, deși simt că întrebarea ar putea fi închisă ca fiind „prea largă” sau ca „duplicat”. Sunt intrigat de modul în care diverse site-uri web precum Github, Twitter (și multe site-uri bazate pe WordPress de asemenea) își deschid API-urile prin dezactivarea restricțiilor CORS pentru toată lumea. Am crezut că dacă dezactivezi CORS doar pentru cererile GET, este destul de inofensiv pentru că doar permiți altora să preia date și nu modifici nimic?

Shariq Hasan Khan Shariq Hasan Khan
28 oct. 2018 08:16:10

Diferența dintre WordPress și alte site-uri este că acestea nu folosesc autentificare bazată pe cookie-uri pentru API, iar utilizarea API-ului necesită trimiterea explicită a informațiilor de utilizator și parolă în fiecare cerere. API-ul WordPress <alertă rant> a fost prost conceput în acest sens și probabil nu a putut fi proiectat mai bine deoarece trebuia să suporte comunicarea nesigură prin HTTP, ceea ce l-a împiedicat să utilizeze tehnica utilizator/parolă, deoarece oricine asculta pe o rețea (de exemplu) WiFi ar fi putut descoperi valorile.

Mark Kaplun Mark Kaplun
29 oct. 2018 04:40:33

faptul că ai cookie-urile setate când ești autentificat este ceea ce atacatorii pot exploata pentru a trimite cereri AJAX ca și cum ar fi inițiate de tine. Cu CORS activat, astfel de cereri vor eșua pentru alte domenii, iar din moment ce tu ești singurul care controlează domeniul, ești în siguranță. Cu cât dezactivezi CORS pentru mai multe site-uri, cu atât mai multe locuri există unde un atacator poate prelua controlul și să te atragă să accesezi acel site. Întrebarea era despre dezactivarea completă a CORS pentru toate site-urile, ceea ce este foarte periculos, dar dacă îl dezactivezi pentru alte domenii pe care le controlezi în totalitate, deși nu este ideal, nu este la fel de rău.

Mark Kaplun Mark Kaplun
29 oct. 2018 04:46:52
Arată celelalte 11 comentarii