Sådan fungerer browsere

En introduktion til webapplikationssikkerhed

Lad os åbne denne serie om Web Application Security med en forklaring på, hvad browsere gør, og hvordan de gør det. Da de fleste af dine kunder vil interagere med din webapplikation gennem en browser, er det bydende nødvendigt at forstå det grundlæggende i disse vidunderlige programmer.

Browseren er en gengivelsesmotor . Dets opgave er at downloade en webside og gengive den på en måde, der er forståelig for et menneske.

Selvom dette er en næsten kriminel overforenkling, er det alt, hvad vi har brug for at vide for nu.

  • Brugeren indtaster en adresse i browserlinjen.
  • Browseren downloader "dokumentet" ved denne URL og gengiver det.

Du er muligvis vant til at arbejde med en af ​​de mest populære browsere som Chrome, Firefox, Edge eller Safari, men det betyder ikke, at der ikke er forskellige browsere derude.

lynx er for eksempel en let tekstbaseret browser, der fungerer fra din kommandolinje. I hjertet af losen ligger de samme nøjagtige principper, som du ville finde i alle andre “mainstream” browsere. En bruger indtaster en webadresse (URL), browseren henter dokumentet og gengiver det - den eneste forskel er det faktum, at lynx ikke bruger en visuel gengivelsesmotor, men snarere en tekstbaseret grænseflade, der får websteder som Google til at se sådan ud :

Vi forstår bredt, hvad en browser gør, men lad os se nærmere på de trin, disse geniale applikationer gør for os.

Hvad gør en browser?

Lang historie kort, en browsers job består hovedsageligt af:

  • DNS-opløsning
  • HTTP-udveksling
  • Gengivelse
  • Skyl og gentag

DNS-opløsning

Denne proces sikrer, at browseren, når brugeren indtaster en URL, ved, hvilken server den skal oprette forbindelse til. Browseren kontakter en DNS-server for at finde, der google.comoversætter til 216.58.207.110, en IP-adresse, som browseren kan oprette forbindelse til.

HTTP-udveksling

Når browseren har identificeret, hvilken server der skal betjene vores anmodning, starter den en TCP-forbindelse med den og begynder HTTP-udvekslingen . Dette er intet andet end en måde for browseren at kommunikere med serveren, hvad den har brug for, og for serveren at svare tilbage.

HTTP er simpelthen navnet på den mest populære protokol til kommunikation på nettet, og browsere taler for det meste via HTTP, når de kommunikerer med servere. En HTTP-udveksling indebærer, at klienten (vores browser) sender en anmodning , og serveren svarer tilbage med et svar .

Når browseren f.eks. Har oprettet forbindelse til serveren bagved google.com, sender den en anmodning, der ser ud som følgende:

GET / HTTP/1.1Host: google.comAccept: */*

Lad os nedbryde anmodningen linje for linje:

  • GET / HTTP/1.1: med denne første linje beder browseren serveren om at hente dokumentet på placeringen /og tilføjer, at resten af ​​anmodningen følger HTTP / 1.1-protokollen (den kan også bruge 1.0eller 2)
  • Host: google.com: dette er den eneste HTTP-header, der er obligatorisk i HTTP / 1.1 . Da serveren muligvis betjener flere domæner ( google.com, google.co.ukosv.), Nævner klienten her, at anmodningen var for den specifikke vært
  • Accept: */*: en valgfri overskrift, hvor browseren fortæller serveren, at den accepterer enhver form for svar tilbage. Serveren kan have en ressource, der er tilgængelig i JSON-, XML- eller HTML-formater, så den kan vælge det format, den foretrækker

Når browseren, der fungerer som klient , er færdig med sin anmodning, er det serverens tur at svare tilbage. Sådan ser et svar ud:

HTTP/1.1 200 OKCache-Control: private, max-age=0Content-Type: text/html; charset=ISO-8859-1Server: gwsX-XSS-Protection: 1; mode=blockX-Frame-Options: SAMEORIGINSet-Cookie: NID=1234; expires=Fri, 18-Jan-2019 18:25:04 GMT; path=/; domain=.google.com; HttpOnly
......

Whoa, det er en masse information at fordøje. Serveren fortæller os, at anmodningen var vellykket ( 200 OK) og tilføjer et par overskrifter til svaret . Den annoncerer for eksempel, hvilken server der behandlede vores anmodning ( Server: gws), hvad X-XSS-Protectionpolitikken i dette svar er, osv.

Lige nu behøver du ikke forstå hver eneste linje i svaret. Vi vil dække HTTP-protokollen, dens overskrifter og så videre senere i denne serie.

For nu er alt hvad du behøver at forstå, at klienten og serveren udveksler oplysninger, og at de gør det via HTTP.

Gengivelse

Sidst, men ikke mindst, gengivelsesprocessen . Hvor god ville en browser være, hvis det eneste, den ville vise brugeren, er en liste over sjove karakterer?

......

I svarets hoveddel inkluderer serveren repræsentationen af ​​svaret i henhold til Content-Typeoverskriften. I vores tilfælde blev indholdstypen indstillet til text/html, så vi forventer HTML-markering i svaret - hvilket er præcis det, vi finder i kroppen.

Det er her, en browser virkelig skinner. Det analyserer HTML, indlæser yderligere ressourcer inkluderet i markeringen (for eksempel kan der være JavaScript-filer eller CSS-dokumenter at hente) og præsenterer dem for brugeren så hurtigt som muligt.

Endnu en gang er slutresultatet noget, som den gennemsnitlige Joe kan forstå.

For en mere detaljeret version af, hvad der virkelig sker, når vi rammer enter i adresselinjen i en browser, vil jeg foreslå at læse "Hvad sker der når ...", et meget detaljeret forsøg på at forklare mekanikken bag processen.

Da dette er en serie, der er fokuseret på sikkerhed, vil jeg komme med et tip om, hvad vi lige har lært: angribere lever let af sårbarheder i HTTP-udvekslings- og gengivelsesdelen . Sårbarheder og ondsindede brugere lurer også andre steder, men en bedre sikkerhedstilgang på disse niveauer giver dig allerede mulighed for at gøre fremskridt med at forbedre din sikkerhedsstilling.

Leverandører

De 4 mest populære browsere derude tilhører forskellige leverandører:

  • Chrome fra Google
  • Firefox fra Mozilla
  • Safari fra Apple
  • Edge af Microsoft

Udover at kæmpe med hinanden for at øge deres markedsindtrængning, interagerer sælgerne også med hinanden for at forbedre webstandarder , som er en slags “minimumskrav” til browsere.

W3C er kroppen bag udviklingen af ​​standarderne, men det er ikke usædvanligt, at browsere udvikler deres egne funktioner, der i sidste ende gør det til webstandarder, og sikkerhed er ingen undtagelse derfra.

Chrome 51 introducerede for eksempel SameSite-cookies, en funktion der gør det muligt for webapplikationer at slippe af med en bestemt type sårbarhed kendt som CSRF (mere om dette senere). Andre leverandører besluttede, at dette var en god idé og fulgte trop, hvilket førte til, at SameSite var en webstandard: Fra nu af er Safari den eneste store browser uden SameSite cookie-understøttelse.

Dette fortæller os to ting:

  • Safari ser ikke ud til at bekymre sig nok om deres brugeres sikkerhed (bare en sjov: SameSite-cookies vil være tilgængelige i Safari 12, som muligvis allerede er frigivet, når du læser denne artikel)
  • at lappe en sårbarhed i en browser betyder ikke, at alle dine brugere er sikre

Det første punkt er et skud på Safari (som jeg nævnte, bare en sjov!), Mens det andet punkt er virkelig vigtigt. Når vi udvikler webapplikationer, behøver vi ikke bare sørge for, at de ser ens ud på tværs af forskellige browsere, men også at de sikrer, at vores brugere er beskyttet på samme måde på tværs af platforme.

Din strategi mod websikkerhed skal variere alt efter hvad en browsers leverandør tillader os at gøre . I dag understøtter de fleste browsere det samme sæt funktioner og afviger sjældent fra deres almindelige køreplan, men tilfælde som ovenstående sker stadig, og det er noget, vi skal tage i betragtning, når vi definerer vores sikkerhedsstrategi.

In our case, if we decide that we’re going to mitigate CSRF attacks only through SameSite cookies, we should be aware that we’re putting our Safari users at risk. And our users should know that too.

Last but not least, you should remember that you can decide whether to support a browser version or not: supporting each and every browser version would be impractical (think of Internet Explorer 6). Making sure that the last few versions of the major browsers are supported, though, is generally a good decision. If you don’t plan to offer protection on a particular platform, though, it’s generally advisable to let your users know.

Pro Tip : You should never encourage your users to use outdated browsers, or actively support them. Even though you might have taken all the necessary precautions, other web developers may have not. Encourage users to use the latest supported version of one of the major browsers.

Vendor or standard bug?

The fact that the average user accesses our application through a 3rd party client (the browser) adds another level of indirection towards a clear, secure browsing experience: the browser itself might present a security vulnerability.

Vendors generally provide rewards (aka bug bounties) to security researchers who can find a vulnerability on the browser itself. These bugs are not tied to your implementation, but rather to how the browser handles security on its own.

The Chrome reward program, for example, lets security engineers reach out to the Chrome security team to report vulnerabilities they have found. If these vulnerabilities are confirmed, a patch is issued, a security advisory notice is generally released to the public, and the researcher receives a (usually financial) reward from the program.

Companies like Google invest a relatively good amount of capital into their Bug Bounty programs, as it allows them to attract researchers by promising a financial benefit should they find any problem with the application.

In a Bug Bounty program, everyone wins: the vendor manages to improve the security of its software, and researchers get paid for their findings. We will discuss these programs later on, as I believe Bug Bounty initiatives deserve their own section in the security landscape.

Jake Archibald is a developer advocate at Google who recently discovered a vulnerability impacting more than one browser. He documented his efforts, how he approached different vendors, and their reactions in an interesting blog post that I’d recommend you read.

A browser for developers

By now, we should have understood a very simple but rather important concept: browsers are simply HTTP clients built for the average internet surfer.

They are definitely more powerful than a platform’s bare HTTP client (think of NodeJS’s require('http'), for example), but at the end of the day, they’re “just” a natural evolution of simpler HTTP clients.

As developers, our HTTP client of choice is probably cURL by Daniel Stenberg, one of the most popular software programs web developers use on a daily basis. It allows us to do an HTTP exchange on-the-fly, by sending an HTTP request from our command line:

$ curl -I localhost:8080
HTTP/1.1 200 OKserver: ecstatic-2.2.1Content-Type: text/htmletag: "23724049-4096-"2018-07-20T11:20:35.526Z""last-modified: Fri, 20 Jul 2018 11:20:35 GMTcache-control: max-age=3600Date: Fri, 20 Jul 2018 11:21:02 GMTConnection: keep-alive

In the example above, we have requested the document at localhost:8080/, and a local server replied successfully.

Rather than dumping the response’s body to the command line, here we’ve used the -I flag which tells cURL we’re only interested in the response headers. Taking it one step forward, we can instruct cURL to dump a little more information, including the actual request it performs, so that we can have a better look at this whole HTTP exchange. The option we need to use is -v (verbose):

$ curl -I -v localhost:8080* Rebuilt URL to: localhost:8080/* Trying 127.0.0.1...* Connected to localhost (127.0.0.1) port 8080 (#0)> HEAD / HTTP/1.1> Host: localhost:8080> User-Agent: curl/7.47.0> Accept: */*>< HTTP/1.1 200 OKHTTP/1.1 200 OK< server: ecstatic-2.2.1server: ecstatic-2.2.1< Content-Type: text/htmlContent-Type: text/html< etag: "23724049-4096-"2018-07-20T11:20:35.526Z""etag: "23724049-4096-"2018-07-20T11:20:35.526Z""< last-modified: Fri, 20 Jul 2018 11:20:35 GMTlast-modified: Fri, 20 Jul 2018 11:20:35 GMT< cache-control: max-age=3600cache-control: max-age=3600< Date: Fri, 20 Jul 2018 11:25:55 GMTDate: Fri, 20 Jul 2018 11:25:55 GMT< Connection: keep-aliveConnection: keep-alive
<* Connection #0 to host localhost left intact

Just about the same information is available in mainstream browsers through their DevTools.

As we’ve seen, browsers are nothing more than elaborate HTTP clients. Sure, they add an enormous amount of features (think of credential management, bookmarking, history, etc) but the truth is that they were born as HTTP clients for humans. This is important, as in most cases you don’t need a browser to test your web application’s security, as you can simply “curl it” and have a look at the response.

One final thing that I’d like to point out, is that anything can be a browser. If you have a mobile application that consumes APIs through the HTTP protocol, then the app is your browser — it just happens to be a highly customized one you built yourself, one that only understands a specific type of HTTP responses (from your own API).

Into the HTTP protocol

As we mentioned, the HTTP exchange and rendering phases are the ones that we’re mostly going to cover, as they provide the largest number of attack vectors for malicious users.

In the next article, we’re going to take a deeper look at the HTTP protocol and try to understand what measures we should take in order to secure HTTP exchanges.

Originally published at odino.org (29 July 2018).

Du kan følge mig på Twitter - rants er velkomne! ?