Når det gjelder de mest populære Javascript-bibliotekene, må man innrømme at det i løpet av deres utviklingshistorie (9, 6 og 5 år for henholdsvis Angular, React og Vue) har skjedd mye bra når det gjelder sikkerhet, spesielt i forbindelse med sårbarhet for XSS-angrep. Denne artikkelen tar imidlertid for seg de små fellene og prinsippene som utviklere fortsatt bør være oppmerksomme på.
XSS
Vi lever i en tid med rammeverk, ikke språk. Dette innebærer at programmerere bør kunne bekymre seg mindre om mange aspekter ved utviklingen, inkludert sikkerhet. De fleste av dagens backend-rammeverk implementerer sikkerhetsmoduler, som testes av eksterne, spesialiserte selskaper og store organisasjoner. Det er derfor viktig, synkende sikkerhetsbevissthet kan være tydelig, for eksempel mellom unge programmerere, som tar mer ansvar for produktene, spesielt når det gjelder frilansarbeid.
Et av de vanligste angrepene på klientsiden av applikasjonen er XSS (Cross-Site Scripting). Det utføres ved å injisere kjørbare skript på klientsiden i webapplikasjoner [1] og bruker implementerte HTML-renderingsmetoder eller Javascript kode evaluatorer som utfører den. XSS er relativt lukrativt ettersom mange ulike data kan samles inn, inkludert øktinformasjonskapsler eller brukerdata, og det kan installere et sporingsprogram som for eksempel en keylogger, noe som gjør det farlig for både brukere og bedriftseiere. Noen ganger utføres andre former for angrep for å tillate XSS på siden, for eksempel SQL-injeksjon.
Eksempel
Innloggingsskjemaet på siden gjengir loginName-parameteren som sendes i GET-forespørselen i innloggingsnavnet. Verdien behandles verken av server- eller klientsiden av applikasjonen. Ved å be om det: http://localhost:8080/login?name=<script>alert(document.cookies)</script>
kode kjøres og data eksponeres
Dette er et eksempel på en Reflektert XSS-angrep, der skript injiseres gjennom en spesielt forberedt URL-adresse som sendes til offeret og gjenspeiles av serverens svar. Andre kjente populære former for angrep er som følger:
- Lagret XSS utføres med data som er lagret på serversiden, vanligvis ved hjelp av skjemaer som er tilgjengelige i applikasjonen. Klientapplikasjonen gjengir kode som for eksempel er lagret i en database.
- DOM XSS utfører et XSS-angrep uten bruk av serversiden. I den videre delen av artikkelen vil vi fokusere på denne angrepsformen.
Aktuelle sårbarheter i React- og Vue-bibliotekene
For de nåværende versjonene av React/Vue er det oppdaget to store problemer som ennå ikke er offisielt løst. Den første sårbarheten er den samme for alle rammeverkene og er knyttet til metoder som tillater gjengivelse av rå HTML i maler: v-html og dangerouslySetInnerHTML, for henholdsvis Vue og React. Dokumentasjonen [2] informerer leserne om at uklokt bruk kan utsette brukerne for XSS-angrep. Hvis det ikke finnes andre alternativer for å løse problemet, må du sørge for at dataene er filtrert og unnsluppet. Selv om de er farlige, bør du ikke forvente at disse metodene blir fikset. Bruk dem på egen risiko.
I første kvartal 2018 ble det oppdaget en stor feil i React, som muliggjorde direkte kjøring av kode ved å angi egenskapen for taggelementet. Overføring av eksempelkode i attributter, for eksempel javascript:alert(1)
og kjører en gjengitt lenke, vil koden kjøres. Dette problemet [4] er fortsatt åpent, og ingen løsning er utarbeidet og slått sammen, så sørg for at koden din er trygg. Eksempler som er foreslått i den offisielle diskusjonen, foreslår noen måter å overvinne dette problemet på.
Hvis det ikke er mulig å oppdatere til de nyeste versjonene, må du sørge for at gamle problemer ikke skaper problemer for deg ved å sikre at koden din ikke er eksponert for:
- barn node injeksjon - React, bruk av React.createElement [5]
- serverside-rendering - React/Vue [6]
- CSS-injeksjon [8]
Det handler fortsatt om Javascript. Det handler fortsatt om front-end
Ikke glem at Javascript som språk, i tillegg til selve rammeverkene eller bibliotekene, har noen farlige funksjoner som må unngås eller brukes med forsiktighet. De er vanligvis relatert til DOM-manipulering eller skriptutførelse. eval() representerer flaggskipfunksjoner av denne typen og er ekstremt farlig fordi den utfører gitt stringifisert kode direkte [9]. Ta også en bedre titt på koden din når du finner en av disse funksjonene:
- document.write
- document.writeln
- (element).innerHTML
- (element).outerHTML
- (element).insertAdjacentHTML
Her kan det være nyttig å bruke linters med riktig regelsett for å finne slike sårbare punkter. Det finnes også mange åpne eller kommersielle kodeanalysatorer som kan hjelpe deg med å oppdage sikkerhetshull i utviklet kode.
Uansett hvilket bibliotek/rammeverk som velges, må vi fortsatt huske på grunnleggende prinsipper knyttet til frontend-utvikling. For det første må du alltid sørge for at den eksterne koden du injiserer, kommer fra en pålitelig kilde. Revisjon avhengighetene dine, og velg dem med omhu. Noen av dem kan inneholde alvorlige sårbarheter som kan eksponere koden din, selv om alt er i orden med selve koden. Du kan lese mer om sikkerhet i avhengigheter her:
https://thecodest.co/blog/security-in-javascript-packages/
Bør du fortsatt være bekymret?
Ja - og jeg oppfordrer alle til aldri å stole på eksterne biblioteker eller seg selv når det gjelder sikkerhet. Uansett hvor sikker du forventer at programvaren din skal være, bør du alltid gjøre en innsats for å teste den så mye som mulig med tanke på vanlige angrepsformer [10].
- https://reactjs.org/docs/dom-elements.html#dangerouslysetinnerhtml
- https://vuejs.org/v2/guide/syntax.html#Raw-HTML
- https://github.com/facebook/react/issues/12441
- http://danlec.com/blog/xss-via-a-spoofed-react-element
- https://medium.com/node-security/the-most-common-xss-vulnerability-in-react-js-applications-2bdffbcc1fa0
- https://github.com/dotboris/vuejs-serverside-template-xss
- https://frontarm.com/james-k-nelson/how-can-i-use-css-in-js-securely/
- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/eval#Do_not_ever_use_eval!
Les mer om dette:
5 feil du bør unngå når du vedlikeholder et prosjekt i PHP
PHP Utvikling. Symfony-konsollkomponent - tips og triks
Hvorfor trenger vi Symfony Polyfill (... og hvorfor vi ikke bør gjøre det)