Advertisement
  1. Code
  2. HTML5

HTML5 Beherskelse: Web-sikkerhed

Scroll to top
Read Time: 9 min
This post is part of a series called HTML5 Mastery Class.
HTML5 Mastery: The Browsing Context
HTML5 Mastery: DOM Mutations

() translation by (you can also view the original English article)

HMTL5 Mastery series imageHMTL5 Mastery series imageHMTL5 Mastery series image

Sikkerhed er et emne, der kommer op fra tid til anden. Det er ikke et problem fra begyndelsen, men når noget slemt sker, det er normalt betragtes som at være dens skyld. Softwaren er kompleks, menneskelige programmering maskinen langtfra er perfekt, og brugeren kan ikke følge bedste praksis enten. Så hvordan kan vi skabe et sikkert system?

Internettet er en af de mest usikre steder. Computere med potentielle sikkerhedsrisici forbundet med hinanden. Servere, der kan modtage vilkårlige data. Klienter, der udfører kode fra ukendte kilder. Mens vi ikke kan kontrollere sikkerheden af serverne, skal vi gøre noget for at beskytte kunderne. Selvom JavaScript kunne betragtes som en sikker scriptsprog, koden for enhver ActiveX, er Flash eller Silverlight plugins absolut ikke. Desuden, selvom JavaScript, selv er i sandkassetilstand, det kan bruges på en sådan måde, at brugeren vil udløse usikre handlinger.

I denne tutorial vil vi se web sikkerhedsmodel i aktion. Vi vil gå ind i bedste praksis og generelle retningslinjer for opbygning af sikre webprogrammer. Vi vil lære hvad cross-oprindelse ressourcedeling politik er og hvordan man kan kontrollere det. Endelig taler vi også om sandboxing (eksterne) indhold.

Sikkerhedsretningslinjer

En af de vigtigste retningslinjer ikke har noget direkte at gøre med HTML direkte: Brug HTTPS! Relationen til HTML ligger naturligvis i fordelingen af vores hypertekst dokumenter. Ikke desto mindre må vi indse, at du bruger HTTPS til transport af vores dokument og bruge HTTPS for vores ressourcer er to forskellige ting. Det er absolut nødvendigt at kontrollere, hvis alle indeholdte ressourcer virkelig bruge ordningen https://

En anden vigtig retningslinje er relateret til brugerdefineret indhold. Når vi tillader brugere at indtaste data i en formular, skal vi være forsigtige. Ikke blot har vi brug at sikre, at webserveren er beskyttet mod almindelige angreb, såsom SQL-injection, vi også nødt til at sikre, at lagrede data ikke bruges i eksekverbar kode uden forsigtighed. For eksempel bør vi tjekke for at strings ikke indeholder noget HTML. HTML alene er ikke skadeligt, men det kan udløse scriptudførelse eller hentning af ressourcen. En måde at tillade brugere at skrive HTML, som vil blive placeret på siden output uden modifikation, er til hvidlisten visse tags og attributter. De andre elementer vil blive undgået.

Vores JavaScripts bør også minimere eksponering og har tillid til tredjeparts-biblioteker. Selvfølgelig bruger vi det umiddelbart påberåbe sig-funktion udtryk (IIFE) at forhindre, at den globale sammenhæng bliver forurenet; en anden grund er imidlertid at ikke lække (sandsynligvis) afgørende indre stater, som kan derefter ændres af andre scripts, frivilligt eller ved en tilfældighed.

1
(function () {
2
  // Standard code here.
3
})();

For os er det helt sikkert god praksis til at stole på 'use strict'; og de befordrede fordele. Ikke desto mindre forhindrer begrænsende kører scriptet ikke os ved hjælp af API'er med potentielt ødelagte data. Cookies og indhold i localStorage kan ændres eller set af brugeren eller andre programmer alt efter betingelser, der ikke kan blive påvirket af os. Vi bør derfor altid gennemføre nogle sanity kontrol, som giver os et vink til at opdage integritet mangler så hurtigt som muligt.

Endelig skal vi sørge for at kun bruge pålidelig tredjeparts ressourcer. Ved hjælp af scripts fra andre servere på vores hjemmeside gør det muligt at mutere siden eller brud på privatlivets fred for vores brugere.

Cross-oprindelse ressourcedeling

Begrebet cross-oprindelse ressourcedeling (CORS) er enkel. Browseren tillader ikke indlejring af særlige ressourcer fra forskellige oprindelser, medmindre oprindelsen udtrykkeligt tillader det. Særlige indtægter kan f.eks. være webskrifttyper eller noget anmodet om via en XMLHttpRequest. Cross-oprindelse AJAX anmodninger er forbudt som standard på grund af deres evne til at udføre avancerede forespørgsler, der introducerer mange scripting sikkerhedsproblemer.

Oprindelsen er dybest set defineret via den anvendte protokol, vært og port kombination. https://a.com er derfor forskellig fra https://a.com, som er forskellig fra https://a.com:8080. De er alle forskellige til http://b.com.

Klienter kan få lov at bruge ressourcer ved at medtage en bestemt header i svaret. Browseren afgør derefter, hvis den nuværende hjemmeside er tilladt at bruge ressourcen eller ej. Oprindelse bestemmes normalt via domænet af den nuværende hjemmeside.

Lad os få et kig på et illustrerende eksempel. I den følgende antager vi, at vores side er placeret på foo.com. Vi anmode om JSON data fra en side hostet på bar.com. Til JSON anmodning bruger vi XMLHttpRequest som vist nedenfor.

1
var xhr = new XMLHttpRequest();
2
xhr.open('GET', 'https://bar.com/users');
3
xhr.addEventListener('load', function (ev) {
4
	if (xhr.status === 200) {
5
		var result = JSON.parse(xhr.responseText);
6
		// ...
7
	}
8
}, false);
9
xhr.send();

Browseren forudser allerede muligheden af en CORS-aktiveret svar ved at tilføje oprindelse header i anmodningen:

1
Origin: http://foo.com

Serveren har nu til at levere det rigtige svar. Ikke blot vil vi have den korrekte JSON skal transporteres, men endnu vi kræver vigtigere CORS specifikke overskrifter. Det er muligt at bruge jokertegn. Eksempelvis vil følgende eksempel give ret til at bruge den ønskede ressource til enhver anmodning.

1
Access-Control-Allow-Origin: *

CORS kan også bruges som et alternativ til JSONP løsning. JSONP bruger scripts til at gøre cross oprindelse AJAX anmodninger resulterer i JSON svar. Før CORS  cross-domæne opkald blev forbudt i almindelighed, men herunder scripts fra forskellige domæner var altid acceptabelt. I de fleste API'er en JSONP blev svar udløst ved at give en særlig forespørgselsparameter, navngivning callback funktion.

Antag, at opkald til http://bar.com/api resultater i følgende JSON svar:

1
{ "name": "example", "factor": 5, "active": true }

JSONP opkaldet til, fx http://bar.com/api?jsonp=setResult ville give os:

1
setResult({ "name": "example", "factor": 5, "active": true });

Da resultatet af JSONP ses kun af elementet <script>, er metoden GET anmodning underforstået. Der er ingen mulighed for at bruge noget andet. CORS giver os meget mere frihed på dette område, således at vi kan også afgøre andre parametre. Dette er alle aktiveret ved at lade os frit bruge standardiserede XMLHttpRequest objektet.

En ideel løsning vil kun falde tilbage til JSONP til ældre browsere, samtidig med at omfavne CORS for nyere dem. Dette vil forhindre mange cross-site scripting (XSS) problemer med oprindelse fra kompromitterede eksterne websteder. Indlejre scripts fra eksterne sider har altid været et risikabelt. En endnu bedre alternativ ville være at omdirigere anmodningen JSON fra vores server til destinationscomputeren. Denne måde, vi taler med vores (betrode) server, der får svaret fra målet, evaluerer sin fornuft og returnerer (gyldige) resultatet.

Sandboxing flag

Hvert dokument kommer med sit eget vindue. Adgang til dette vindue er for det meste bruges proxygodkendelse til vinduet i den aktuelle browser kontekst, som drev den fane, der ser vi. Browsing forbindelse er lavet med flere muligheder, som den overordnede kontekst, skaberen og den første side. Sammen med disse indstillinger, er sikkerhed af flag angivet. Flagene konfigurere muligheder og begrænsninger i konteksten. I realiteten er det muligt at forhindre visse adfærd, som kører scripts eller åbne nye faner.

Hvordan kan vi sætte flag, sikkerhed i en ny sammenhæng? Vi satte forbindelse via attributter, der er knyttet til de elementer, som skal skabe en ny kontekst. I øjeblikket kun iframe element har en attribut, selvom standard rammer ville også passe til den tidligere beskrivelse. Dog standard rammer betragtes som forældet og understøttes derfor ikke rigtig godt. Selvom HTML5 standarden nævner dem, bør de ikke bruges længere.

Der findes en masse flag. De vigtigste er:

  • allow-top-navigation (tillader ændre konteksten top)
  • allow-plugins (muliggør embedobject,...)
  • allow-same-origin (indhold fra samme oprindelse kan tilgås)
  • allow-forms (formularer kan sendes)
  • allow-popups (popups / nye kontekster vil ikke blive blokeret)
  • allow-pointer-lock (muliggør pointer-lock API)
  • allow-scripts (tillader scriptudførelse)

Den <iframe> bruger attributten sandkassen til at angive tilstanden sandboxed.</iframe> Hvis denne attribut ikke er angivet, er alt tilladt som vi kender den. Med denne attribut, er alt forbudt. De tidligere angivne flag derfor aktivere visse funktioner.

Lad os tage et nærmere kig på flaget allow-same-origin. Som standard er politik for en iframe virkelig afslappet. Hvis vi ikke angiver attributten sandbox tillades kun integrerede sider fra det samme domæne til at læse, fx cookies eller Lokal browserlagring for det angivne domæne. Naturligvis forekomme andre risici samt — det er derfor vi normalt ønsker at levere attributten sandbox.

Følgende billede viser standard opførsel i et simpelt diagram. Mens den anden iframe er tilladt adgang til de tidligere anførte indhold, den første er ikke. Årsagen er det andet domæne, fremhævet med gult.

IFrame Standard OriginIFrame Standard OriginIFrame Standard Origin

Så hvordan ændrer dette billede med attributten sandbox? Indhold fra et andet domæne er stadig forbudt. Derfor ser vi kun på de yderligere muligheder for indhold fra samme oprindelse. Som standard behandles selv indhold fra samme oprindelse som om det kom fra en anden oprindelse.

IFrame Sandbox OriginIFrame Sandbox OriginIFrame Sandbox Origin

Der er flere funktioner, som kan kontrolleres eller indstillet til kontekster, men disse er desværre transporteret via deres egne attributter. Et godt eksempel er attributten allowfullscreen. Igen er det kun tilgængelige på en iframe. I princippet tillader applikationer at gå i fuld-raster måde.

Derudover bør vi bemærke attributten seamless for et <iframe> element. Denne attribut kan styling af det overordnede dokument på dokumentet. Det er navnlig kraftfulde sammenholdt med attributten srcdoc, som tillader os at levere kilden til en iframe direkte, uden at kræve http-anmodninger eller bruge en data URI. Denne måde kan vi meget nemt give bruger-indhold uden bekymrende omkring scriptudførelse.

Et eksempel til at vise brugerindhold i en sandboxed miljø er vist nedenfor.

1
<iframe sandbox seamless srcdoc="
2
	<div class=comment>
3
		<h3>Example User</h3>
4
		<span class=comment-content>Custom, but <strong>safe</strong>!</span>
5
	</div>
6
"></iframe>

Sandboxed iframes kan bruges til mange opgaver. For eksempel, hvis vi ønsker at vurdere scripts sikkert, kunne vi passere indhold at evaluere til en speciel handler sidder inde i en iframe. Handleren vil kalde funktionen eval. Den indbyggede ramme er sandboxed til kun at tillade scripting, intet andet. Kan ikke åbnes, ingen popups, navigation kan ikke bruges, og vores hele DOM er adskilt.

Den præcise gennemførelse kræver også HTML5 messaging mellem dokumenter. Vi sender anmodningen om evaluering med metoden postMessage og lytte til svar via message begivenhed.

Vi kan også sandkasse dele af den aktuelle side, ved hjælp af content security policy (CSP). Denne ejendom er normalt transporteres via HTTP-sidehoveder, men HTML giver os mulighed for at sætte det i en <meta> tag.

Et eksempel ser ud som følger. Vi skal bruge den rigtige http-equiv værdi. Indholdet er en række definitioner specifikke for siden.

1
<meta 
2
	http-equiv="Content-Security-Policy" 
3
	content="default-src https://bar.com; child-src 'none'; object-src 'none'"> 

De forskellige definitioner (kaldet politikker) også acceptere jokertegn. Det præcise formål og udseende er stærkt afhængige af den politik, der bliver brugt.

Konklusion

Web security er muligt, selvom det er svært at opnå, og afhænger af en masse (ofte umuligt at kontrollere) eksterne parametre. Hvis vi kan minimere disse eksterne parametre, som indsatte indhold eller scripts, er vi som regel i god form. De fleste angrebsvektorer kan kun bruges fra scripts.

Vi har set, at (inline) rammer og hyperlinks kan justeres med sandboxing flag. Vores egne ressourcer bør kun anvendes med CORS i tankerne.

Referencer

Advertisement
Did you find this post useful?
Want a weekly email summary?
Subscribe below and we’ll send you a weekly email summary of all new Code tutorials. Never miss out on learning about the next big thing.
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.