Mange nettsikkerhetsproblemer kommer fra å stole på brukeren for mye. De fleste brukere av webapplikasjonen din vil bare gjøre det de trenger å gjøre, en nysgjerrig eller ondsinnet bruker vil ofte presse kantene på tilgangen. På disse kanter vises sikkerhetshull ofte i søknaden din. Jeg har skrevet om å forhindre to vanlige typer sikkerhetsproblemer, SQL Injection og Cross Site Request Forgery, i ASP.NET apps før. Denne artikkelen ser på å forhindre Cross Site Scripting, en tredje vanlig type sikkerhetsproblem på nettsteder.
Selv om et moderne rammeverk gjør mye for å gjøre disse angrepene vanskeligere, tror jeg at vi først skal forstå hvordan en app er utsatt for et angrep. Først, la oss se på hva Cross Site Scripting er og hvordan det kan utnyttes.
Cross Site Scripting (ofte forkortet som XSS) tillater injeksjon av ondsinnede skript til et ellers pålitelig nettsted. Denne injeksjonen skjer uten brukerens kunnskap. Det injiserte skriptet utføres som om det kom fra det opprinnelige nettstedet. Det ondskapsfulle skriptet kan dermed få tilgang til eventuelle ressurser på den vertsbaserte nettsiden brukeren vil ha tilgang til, for eksempel informasjonskapsler eller økttokener.
Åpningen for et scriptingangrep på tvers av nettstedet kommer når et webprogram viser innspill fra brukere eller eksterne ressurser uten å korrekt validere eller kodere det. I de fleste overføringsskriptangrep angriper angriperen å injisere JavaScript inn på en pålitelig servers nettside. Angriperen kan også prøve å injisere HTML, Flash eller alt annet nettleseren vil utføre. Uansett skriptet, er målet fortsatt å få nettleseren til å utføre kode for angriperens valg.
Det er tre kategorier av cross-site scripting angrep, delt med injeksjonsmetode og metode for å forhindre angrepet. I den første typen angrep blir skriptet permanent lagret på målserveren og kalles dermed et vedvarende kryssstedskriptangrep. Dette angrepet forsøker å legge inn det skadelige skriptet i noe som for eksempel et forumpost lagret i en database eller et tilsynelatende gunstig felt, som for eksempel en databasens hjemmesider. Med skriptet vedvarende, blir alle besøkende på nettstedet som ser på innlegget, meldingen eller på annen måte kompromittert, et potensielt offer for angrepet.
Angrep som forsøker denne typen angrep, retter seg generelt mot kommentarfelt, fora, sosiale medier og andre felt hvor det er forventet noe vilkårlig sluttbrukerinngang, og er en vanlig del av søknaden. Angriperen kan inkludere skriptet i et foruminnlegg i en ellers gyldig del av en samtale. Hver gang noen ser innlegget, vil skriptet bli utført.
I den andre typen krypteringsskriptangrep, kjent som reflektert cross-site scripting, leverer angriperen det injiserte skriptet til det sårbare nettstedet slik at det umiddelbart vil bli returnert tilbake til brukeren. Vanlige metoder for å gjøre dette, målrett sider hvor brukerinngang blir en del av utgangen på en side. En søkeside kan vise søkeordene til brukeren og kunne gi et utløp for dette angrepet. Det injiserte skriptet i en brukeres inngang bør aldri lagres av webapplikasjonen.
Det tredje cross-site scripting angrep skjer helt i nettleseren. Angrepet fungerer ved å manipulere den interne modellen til nettsiden i nettleseren, kjent som DOM, og refereres til som DOM-baserte angrep. Disse igjen tillater angriperen å utføre skadelig kode, men kode returnert av serveren blir manipulert til kjørbar JavaScript av nettsiden.
Til slutt er et cross-site scripting angrep et cross-site scripting angrep, uansett hvordan det leveres. Siden den injiserte koden kommer fra en ellers klarert server, kan den ofte utføres under nettstedets tillatelser. Det kan derfor fungere som om det var opprinnelig kode på nettsiden.
Et vellykket cross-site scripting-angrep kan tillate tilgang til informasjonskapsler på en nettside. Disse informasjonskapslene kan inneholde sensitiv informasjon, inkludert øktidentifikatorer som tillater angriperen å etterligne den angripne brukeren. Angrepet kan også endre HTML-innhold på en side for å vise et falskt påloggingsskjema og stjele brukerens påloggingsinformasjon. Angriperen kan undersøke og sende innhold på siden som gjør det mulig å fange sensitiv informasjon, for eksempel kontonumre. Et mer avansert angrep kan i realiteten installere en nøkkellogger som sender informasjon som er innført på nettsiden til en angriper.
Mitigating cross script scripting krever ikke tillit til innspill fra en bruker eller en annen ekstern kilde. Webapplikasjonen må behandle disse dataene som potensielt farlige, uansett kilden. La oss se på noen få metoder som er spesifikke for ASP.NET for å forhindre at disse angrepene bruker komponenter som er bygd inn i rammen og fritt tilgjengelige biblioteker.
Nettapplikasjonen skal validere alle innspill til programmet før det blir brukt. Akkurat som med andre injeksjonsangrep som SQL Injection. Programmet validerer fortrinnsvis denne inngangen mot en hvit liste over akseptable verdier. Valideringen fjerner eller erstatter eventuelle uventede komponenter i inngangen med en kodet verdi. En blacklisting-metode, som bare fjerner en liste over kjente uønskede tegn, kan brukes, men er mer sårbar for nye angrepsmetoder.
Hvis vi vet at en verdi alltid skal være et heltall, kan du validere inngangen ved hjelp av kode som:
int medlemId; hvis (! int.TryParse (externalValue, out memberId)) return RedirectToAction ("InputError");
Hvis rammen ikke kan analysere den tidligere hentet externalValue
som et heltall, omdirigerer koden til en side som vil vise en feil. Ellers vet vi det memberId
inneholder en heltallverdi. Denne prosessen fungerer også med andre grunnleggende typer. Noen mer vanlige typer gir også metoder for å validere informasjonen. Nettet Uri
klassen inneholder en metode IsWellFormedUriString
som kan validere en nettadresse. Dette vil tillate validering at en brukers hjemmesideoppføring inneholder en gyldig nettadresse før visning.
var userHomePage = userRecord ["hjemmeside"]; hvis (! Uri.IsWellFormedUriString (newUrl, UriKind.Absolute)) Model.homepage = "none"; else Model.homepage = Html.Encode (userHomePage);
Andre og mer komplekse datatyper trenger mer komplisert validering. Validering av et kredittkortnummerfelt kan fjerne eventuelle tegn i strengen som ikke er siffer. Validering av mer komplekse strenge kan trenge regulære uttrykk. Valideringen av en klasse kan også trenge mer komplekse sjekker.
ASP.NET gir effektiv beskyttelse mot reflekterte angrep ved hjelp av forespørsel validering. Hvis ASP.NET oppdager markering eller kode i en forespørsel, kaster den en "potensielt farlig verdi ble oppdaget" unntak og stopper behandlingen av forespørselen.
Mens verdifullt, er det tidspunkter at du må tillate disse verdiene i en forespørsel. Et vanlig eksempel kommer i å tillate rik tekstinngang i et skjema. I disse tilfellene er forespørselsvalidering dessverre for ofte slått av for hele nettstedet. En bedre løsning slår seg av denne valideringen bare når det er nødvendig. I tidligere versjoner av ASP.NET, legger du til validateRequest = "false"
til Side
Direktivet i Webforms ville slå valideringen av for en side. I ASP.NET MVC, legger du til [ValidateInput (false)]
Attributt til en kontrolleringshandling slår av validering for den handlingen, mens du legger til [AllowHtml]
attributt slår av validering for et felt.
ASP.NET 4.0 endret forespørsel validering på flere måter. Denne og senere versjoner av rammene gjør validering tidlig i HTTP-forespørselen. Valideringen gjelder også for alle ASP.NET-forespørsler og ikke bare .aspx
sideforespørsler. Dette inkluderer også egendefinerte HTTP-moduler. Sider som stole på den opprinnelige oppførselen, kan gå tilbake til den eldre metoden ved å sette inn requestValidationMode
attributt i web.config
fil til versjon 2.0
.
Enda bedre, er å deaktivere dette bare for sider der det trengs, ved hjelp av syntaksen i web.config
fil:
ASP.NET 4.5 la til evnen til å utsette validering til å be om dataene. Innstilling av requestValidationMode
attributt i din web.config
fil til versjon 4.5
aktiverer denne nye oppførselen.
ASP.NET 4.5 har også lagt til HttpRequest.Unvalidated
eiendom. Bruk av denne egenskapen gjør det lettere å få tilgang til den ugyldige formverdien når det er nødvendig. Ved å kombinere forsinket validering og ubekreftede
eiendom, kan du få tilgang til de ugyldige verdiene når det er nødvendig, men beskytte andre skjemainnganger.
Før du viser eksterne data på en nettside, bør HTML-koden være kodet slik at den ikke behandles av nettleseren. For eksempel, ta en ASP.NET-side skrevet slik at en melding kan sendes for visning, for eksempel en statusoppdatering. Et program kan bruke denne siden til å vise brukeren at kontoen sin var opprettet uten feil. Nettadressen for denne siden vil normalt se ut som http: // appname / placeorder / konto + Laget
. Den resulterende siden viser meldingen til brukeren med et felt, for eksempel:
<%= Html.Label("Message", Model.message) %>
... og vises som:
Hvis vi endrer URL-anropet til http: / appname / placeorder /
, vi får nå noe annet.
Skriptet kan være noe selvfølgelig og ikke bare den ufarlige varselboksen som vises her. Forespørsel Bekreftelse ville fange de ovennevnte eksemplene og returnere et unntak før visning. Hvis slått av skjønt, forhindrer kodingen av utgangen angrepet.
ASP.NET gjør det enkelt å kode inn data for å forhindre angrep. Tidlige versjoner av MVC ved hjelp av Webforms syntaks inneholdt ofte kode som dette som ikke koder HTML.
<%= status >
Du måtte manuelt kode utdataene slik at noen HTML kunne konverteres til et visningsformat. Så <
tegn blir strengen <
. De Html.Encode
funksjonen gir denne konverteringen. Den sikrere form for kode blir således:
<%= Html.Encode(status) >
ASP.NET MVC introduserte senere en syntaks for å gjøre dette i ett trinn ved å erstatte <=
med <:
så koden kan forkortes til:
<%: status >
Ved å bruke Razor-visningsmotoren, er all utdata HTML-kodet, med mindre du spesifikt bruker en metode for ikke å kode den. I Razor blir koden som er ekvivalent med ovennevnte:
@status
Razor håndterer automatisk HTML-koding av hva som helst strengen status
inneholder. I et tilfelle hvor du må gjøre de rå dataene, kan du bruke HTML.Raw ()
metode. For å vise resultatet uten koding kan vi bruke:
@ Html.Raw (status)
I dette eksemplet vil koden ovenfor gjøre vår søknad sårbar en gang til. Så, det er noen omstendigheter der du ikke skal kode inn output. Hvis du deaktiverer denne funksjonen på et felt, må du være ekstra forsiktig for å sikre at dataene blir sanitisert før visning. Heldigvis finnes det et bibliotek som hjelper med dette, samtidig som du gjør mer for å beskytte din søknad fra cross scripting.
Hvis du skriver et ASP.NET-program, bør du bruke AntiXSS-biblioteket for ASP.NET. Fra prosjektets nettsted, "AntiXSS gir et myriade av koding funksjoner for brukerinngang, inkludert HTML, HTML attributter, XML, CSS og JavaScript."
Biblioteket inneholder metoder som er fokusert på å sanitere eksterne data basert på den tilsiktede bruken av dataene. Disse metodene bruker den foretrukne hvite listebaserte tilnærmingen. Dette betyr at kodede data, beregnet for en HTML-attributt, kan sanitiseres for å inneholde bare gyldige data for et HTML-attributt. Den tradisjonelle ASP.NET HtmlEncode
Metoder bruker den svarte oppføringen tilnærmingen som bare koder for visse, potensielt farlige tegn.
Microsoft begynte å inkludere kjernerutiner fra dette biblioteket til ASP.NET 4.5 i en ny System.Web.Security.AntiXss
navnerom. Du kan også sette opp rammen for å bruke disse AntiXSS-metodene i stedet for de innebygde kodingsrutinene. Du gjør dette ved å sette inn encoderType
attributt av httpRuntime
i web.config
fil for søknaden:
Hvis søknaden din har noen signifikant visning av utvendige data, vil bruken av AntiXSS gjøre mye for å beskytte din applikasjon fra cross scripting. Hvis du bruker ASP.NET 4.5, gir du enda bedre beskyttelse for webapplikasjonen din, og deretter endrer du programmet for å bruke de nye AntiXSS-metodene for standardkoding..
Det er vanskeligere å forhindre cross-site scripting enn det i utgangspunktet virker. OWASP lister over 80 vektorer som kan målrettes ved bruk av cross-site scripting angrep. Den organisasjonen viser også disse sikkerhetsproblemene som tredje i 2013-listen over topp ti websårbarheter.
Hvis du ikke sørger for at all ekstern data som er brakt inn i søknaden din, er skikkelig rømt eller ikke validerer innspill før du plasserer den på en utskriftsside, lar du webapplikasjonen være sårbar for å krysse nettstedskripting. I ASP.NET kan dette gjøres av: