Un manual pentru dezvoltatori web pe CORS, CSP, HSTS și toate acronimele de securitate web!

Există multe motive pentru a afla despre securitatea web, cum ar fi:

  • Sunteți un utilizator îngrijorat, care este îngrijorat de scurgerea datelor dvs. personale
  • Sunteți un dezvoltator web preocupat, care dorește să își facă aplicațiile web mai sigure
  • Ești un dezvoltator web care aplică la locuri de muncă și vrei să fii pregătit dacă intervievatorii îți pun întrebări despre securitatea web

si asa mai departe.

Ei bine, această postare va explica câteva acronime comune de securitate web într-un mod ușor de înțeles, dar totuși precis.

Înainte de a face acest lucru, să ne asigurăm că înțelegem câteva concepte de bază ale securității.

Două concepte de bază ale securității

Nimeni nu este 100% sigur.

Nu există nicio noțiune de a fi 100% protejat împotriva pirateriei. Dacă cineva îți spune asta vreodată, se înșală.

Un strat de protecție nu este suficient.

Nu poți spune doar …

Oh, pentru că am implementat CSP, sunt în siguranță. Pot elimina scripturile inter-site din lista mea de vulnerabilități, deoarece asta nu se poate întâmpla acum.

Poate că asta este un lucru dat unora, dar este ușor să te regăsești gândind astfel. Cred că un motiv pentru care programatorii se pot găsi cu ușurință gândindu-se astfel este că o mare parte din codificare este alb-negru, 0 sau 1, adevărat sau fals. Securitatea nu este atât de simplă.

Vom începe cu unul pe care toată lumea îl întâlnește destul de devreme în călătoria lor de dezvoltare web. Și apoi te uiți la StackOverflow și găsești o grămadă de răspunsuri care îți spun cum să-l ocolești.

Partajarea resurselor între origine (CORS)

Ați primit vreodată o eroare care arăta așa ceva?

No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'null' is therefore not allowed access.

Cu siguranță nu ești singur. Și apoi îl Google, și cineva vă spune să obțineți această extensie care vă va face să dispară toate problemele!

Super, nu?

CORS este acolo pentru a vă proteja, nu pentru a vă răni!

Pentru a explica modul în care vă ajută CORS, să vorbim mai întâi despre cookie-uri, în special cookie-uri de autentificare. Cookie-urile de autentificare sunt folosite pentru a informa un server că sunteți conectat și sunt trimise automat cu orice solicitare pe care o faceți către acel server.

Să presupunem că v-ați conectat la Facebook și că utilizează cookie-uri de autentificare. Faceți clic pe bit.ly/r43nugi care te redirecționează către superevilwebsite.rocks. Un script în interior superevilwebsite.rocks face o cerere din partea clientului către facebook.com care trimite cookie-ul dvs. de autentificare!

Într-o lume fără CORS, aceștia ar putea aduce modificări contului dvs., fără să știți. Până când, desigur, postează bit.ly/r43nugi pe cronologia dvs. și toți prietenii dvs. dau clic pe ea și apoi postează bit.ly/r43nugi pe toate calendarele prietenilor tăi și apoi ciclul continuă într-o schemă malefică, care cucerește toți utilizatorii Facebook, iar lumea este consumată de superevilwebsite.rocks. ?

Cu toate acestea, într-o lume CORS, Facebook ar permite doar cererile cu o origine de facebook.com pentru a edita datele de pe serverul lor. Cu alte cuvinte, acestea ar limita partajarea resurselor între origini. S-ar putea să întrebi …

Ei bine, superevilwebsite.rocks poate schimba doar antetul de origine la cererea lor, astfel încât să pară că vine de pe facebook.com?

Pot încerca, dar nu va funcționa, deoarece browserul îl va ignora și va folosi originea reală.

Ok, dar ce se întâmplă dacă superevilwebsite.rocks a făcut cererea pe partea de server?

În acest caz, ar putea ocoli CORS, dar nu vor câștiga, deoarece nu vor putea trimite cookie-ul dvs. de autentificare pentru călătorie. Scriptul ar trebui să fie executat pe partea clientului pentru a avea acces la cookie-urile dvs. din partea clientului.

Politica de securitate a conținutului (CSP)

Pentru a înțelege CSP, trebuie mai întâi să vorbim despre una dintre cele mai frecvente vulnerabilități de pe web: XSS, care înseamnă cross-site scripting (yay – un alt acronim).

XSS este atunci când o persoană malefică injectează JavaScript în codul dvs. din partea clientului. Ai putea crede…

Ce vor face? Schimbați o culoare din roșu în albastru?

Să presupunem că cineva a injectat cu succes JavaScript în codul client al unui site pe care îl vizitați.

Ce ar putea face pentru a fi rău intenționat?

  • Ei ar putea face cereri HTTP către un alt site care se preface că sunteți dvs.
  • Ar putea adăuga o etichetă de ancorare care vă trimite la un site web care arată identic cu cel pe care vă aflați, cu unele caracteristici ușor diferite, rău intenționate.
  • Ar putea adăuga o etichetă de script cu JavaScript în linie.
  • Ar putea adăuga o etichetă de script care preia undeva un fișier JavaScript la distanță.
  • Aceștia ar putea adăuga un iframe care acoperă pagina și arată ca o parte a site-ului web care vă solicită să vă introduceți parola.

Posibilitățile sunt nelimitate.

CSP încearcă să prevină acest lucru prin limitarea:

  • ce poate fi deschis într-un iframe
  • ce foi de stil pot fi încărcate
  • unde se pot face cereri etc.

Deci, cum funcționează?

Când faceți clic pe un link sau introduceți o adresă URL a site-ului web în bara de adrese a browserului dvs., browserul dvs. face o solicitare GET. În cele din urmă, se îndreaptă spre un server care servește HTML împreună cu unele antete HTTP. Dacă sunteți curios cu privire la anteturile pe care le primiți, deschideți fila Rețea din consola dvs. și accesați câteva site-uri web.

Este posibil să vedeți un antet de răspuns care arată astfel:

content-security-policy: default-src * data: blob:;script-src *.facebook.com *.fbcdn.net *.facebook.net *.google-analytics.com *.virtualearth.net *.google.com 127.0.0.1:* *.spotilocal.com:* 'unsafe-inline' 'unsafe-eval' *.atlassolutions.com blob: data: 'self';style-src data: blob: 'unsafe-inline' *;connect-src *.facebook.com facebook.com *.fbcdn.net *.facebook.net *.spotilocal.com:* wss://*.facebook.com:* https://fb.scanandcleanlocal.com:* *.atlassolutions.com attachment.fbsbx.com ws://localhost:* blob: *.cdninstagram.com 'self' chrome-extension://boadgeojelhgndaghljhdicfkmllpafd chrome-extension://dliochdbjfkdbacpmhlcpmleaejidimm;

Aceasta este politica de securitate a conținutului facebook.com. Să-l reformatăm pentru a ușura citirea:

content-security-policy:
default-src * data: blob:;

script-src *.facebook.com *.fbcdn.net *.facebook.net *.google-analytics.com *.virtualearth.net *.google.com 127.0.0.1:* *.spotilocal.com:* 'unsafe-inline' 'unsafe-eval' *.atlassolutions.com blob: data: 'self';

style-src data: blob: 'unsafe-inline' *;

connect-src *.facebook.com facebook.com *.fbcdn.net *.facebook.net *.spotilocal.com:* wss://*.facebook.com:* https://fb.scanandcleanlocal.com:* *.atlassolutions.com attachment.fbsbx.com ws://localhost:* blob: *.cdninstagram.com 'self' chrome-extension://boadgeojelhgndaghljhdicfkmllpafd chrome-extension://dliochdbjfkdbacpmhlcpmleaejidimm;

Acum, să descompunem directivele.

  • default-src restricționează toate celelalte directive CSP care nu sunt listate în mod explicit.
  • script-src restricționează scripturile care pot fi încărcate.
  • style-src restricționează foile de stil care pot fi încărcate.
  • connect-src restricționează adresele URL care pot fi încărcate folosind interfețe script, așa că fetch, XHR, ajax etc.

Rețineți că există mult mai multe directive CSP decât doar aceste patru prezentate mai sus. Browserul va citi antetul CSP și va aplica acele directive pentru tot ceea ce se află în fișierul HTML care a fost difuzat. Dacă directivele sunt stabilite în mod corespunzător, ele permit doar ceea ce este necesar.

Dacă nu există un antet CSP, atunci totul merge și nimic nu este restricționat. Oriunde vezi * , acesta este un wildcard. Vă puteți imagina înlocuirea * cu orice și va fi permis.

HTTPS sau HTTP Secure

Cu siguranță ați auzit despre HTTPS. Poate ai auzit pe unii oameni spunând …

De ce îmi pasă să folosesc HTTPS dacă sunt doar pe un site web jucând un joc.

Sau poate ai auzit de cealaltă parte …

Ești nebun dacă site-ul tău nu are HTTPS. Este 2018! Nu aveți încredere în nimeni care spune altceva.

Poate ați auzit că Chrome va marca acum site-ul dvs. ca nesigur dacă nu este HTTPS.

În esență, HTTPS este destul de simplu. HTTPS este criptat și HTTP nu.

Deci, de ce contează acest lucru dacă nu trimiteți date sensibile?

Pregătește-te pentru un alt acronim … MITM, care înseamnă Man in the Middle.

Dacă utilizați Wi-Fi public fără parolă la o cafenea, este destul de ușor pentru cineva să acționeze ca routerul dvs., astfel încât toate cererile și răspunsurile să treacă prin ele. Dacă datele dvs. nu sunt criptate, atunci pot face tot ce vor cu ele. Aceștia pot edita HTML, CSS sau JavaScript înainte ca acesta să ajungă chiar în browserul dvs. Având în vedere ceea ce știm despre XSS, vă puteți imagina cât de rău ar putea fi acest lucru.

Ok, dar cum se face că computerul și serverul meu știu cum să cripteze / decripteze, dar acest MITM nu?

Acolo intră SSL (Secure Sockets Layer) și, mai recent, TLS (Transport Layer Security). TLS a preluat SSL în 1999 ca tehnologie de criptare utilizată în HTTPS. Exact modul în care funcționează TLS nu intră în sfera acestui articol.

HTTP Strict-Transport-Security (HSTS)

Acesta este destul de simplu. Să folosim din nou antetul Facebook ca exemplu:

strict-transport-security: max-age=15552000; preload
  • max-age specifică cât timp ar trebui să-și amintească un browser pentru a forța utilizatorul să acceseze un site web folosind HTTPS.
  • preload nu este important pentru scopurile noastre. Este un serviciu găzduit de Google și nu face parte din specificațiile HSTS.

Acest antet se aplică numai dacă ați accesat site-ul folosind HTTPS. Dacă ați accesat site-ul prin HTTP, antetul este ignorat. Motivul este că, pur și simplu, HTTP este atât de nesigur încât nu poate fi de încredere.

Să folosim exemplul Facebook pentru a ilustra în continuare modul în care acest lucru este util în practică. Accesați facebook.com pentru prima dată și știți că HTTPS este mai sigur decât HTTP, așa că îl accesați prin HTTPS, https://facebook.com. Când browserul dvs. primește codul HTML, acesta primește antetul de mai sus, care îi spune browserului să vă redirecționeze forțat către HTTPS pentru solicitări viitoare. O lună mai târziu, cineva îți trimite un link către Facebook folosind HTTP, http://facebook.com, și faceți clic pe el. Deoarece o lună este mai mică decât cele 15552000 secunde specificate de max-age directivă, browserul dvs. va trimite solicitarea ca HTTPS, prevenind un potențial atac MITM.

Gânduri de închidere

Securitatea web este importantă indiferent unde vă aflați în călătoria dvs. de dezvoltare web. Cu cât te expui mai mult la el, cu atât vei fi mai bine. Securitatea este ceva care ar trebui să fie important pentru toată lumea, nu doar pentru persoanele care o numesc în mod explicit în funcția lor! ?