Vi er under angrep! 23+ Node.js sikkerhetspraksis

Vi er under angrep! 23+ Node.js sikkerhetspraksis

Innsamlet, kuratert og skrevet av: Yoni Goldberg, Kyle Martin og Bruno Scheufler

Teknisk anmelder: Liran Tal (Node.js Security Working Group)

Velkommen til vår omfattende liste over sikkerhetspraksis for Node.js som oppsummerer og kuraterer topprangerte artikler og blogginnlegg

Få ord før vi begynner

Nettangrep eksploderer i disse dager når sikkerhet kommer foran på scenen. Vi har samlet over 23 Node.js sikkerhetspraksis (+40 andre generiske sikkerhetspraksiser) fra alle topprangerte artikler over hele verden. Arbeidet her er en del av vårt Node.js beste praksis-GitHub-lager, som inneholder mer enn 80 Node.js-praksis. Merk: Mange elementer har en lese mer lenke til en utdyping om emnet med kodeeksempel og annen nyttig informasjon.

Få beste praksis per uke via Twitter-feeden vår

1. Omfavne sikkerhetsregler for linter

TL; DR: Benytt deg av sikkerhetsrelaterte linter-plugins som eslint-plugin-sikkerhet for å fange sikkerhetsproblemer og problemer så tidlig som mulig - mens de blir kodet. Dette kan bidra til å fange sikkerhetssvakheter som å bruke eval, påkalle en barneprosess eller importere en modul med en ikke-streng bokstavelig (f.eks. Brukerinput). Klikk "Les mer" nedenfor for å se kodeeksempler som vil fanges av en sikkerhetslint

Ellers: Det som kunne vært en grei sikkerhetssvakhet under utbygging blir et stort tema i produksjonen. Prosjektet kan heller ikke følge konsekvente kodesikkerhetspraksis, noe som fører til at sårbarheter blir introdusert eller sensitive hemmeligheter begått i eksterne depoter

Les mer: Linter regler

Fôring trenger ikke være bare et verktøy for å håndheve pedantiske regler om hvitrom, semikolon eller evalueringer. ESLint gir et kraftig rammeverk for å eliminere et bredt utvalg av potensielt farlige mønstre i koden din (vanlige uttrykk, inndatavalidering og så videre). Jeg tror det gir et kraftig nytt verktøy som er verdig å vurdere av sikkerhetsbevisste JavaScript-utviklere. (Adam Baldwin)
Flere sitater og kodeeksempler her

2. Begrens samtidig forespørsler ved hjelp av mellomvare

TL; DR: DOS-angrep er veldig populære og relativt enkle å utføre. Implementere hastighetsbegrensning ved bruk av en ekstern tjeneste som skybelastningsbalansører, skybrannmurer, nginx, hastighetsbegrensende pakke eller (for mindre og mindre kritiske apper) en hastighetsbegrensende mellomvare (f.eks. Ekspressfrekvensgrense)

Ellers: En applikasjon kan bli utsatt for et angrep som resulterer i en benektelse av tjenesten der virkelige brukere mottar en forringet eller utilgjengelig tjeneste.

Les mer: Gjennomfør hastighetsbegrensning

3. Trekk ut hemmeligheter fra konfigurasjonsfiler eller bruk pakker for å kryptere dem

TL; DR: Oppbevar aldri ren teksthemmeligheter i konfigurasjonsfiler eller kildekode. Bruk i stedet hemmelige styringssystemer som Vault-produkter, Kubernetes / Docker Secrets, eller bruk miljøvariabler. Som et siste resultat, må hemmeligheter som er lagret i kildekontroll krypteres og administreres (rullende nøkler, utløper, revisjon osv.). Bruk forhåndsforpliktende / skyvkroker for å forhindre å begå hemmeligheter ved et uhell

Ellers: Kildekontroll, selv for private depoter, kan feilaktig offentliggjøres, på hvilket tidspunkt alle hemmeligheter blir utsatt. Tilgang til kildekontroll for en ekstern part vil utilsiktet gi tilgang til relaterte systemer (databaser, apis, tjenester osv.).

Les mer: Hemmelig ledelse

4. Forhindre sårbarheter med injeksjonsspørsmål med ORM / ODM-biblioteker

TL; DR: For å forhindre SQL / NoSQL-injeksjon og andre ondsinnede angrep, bruk alltid et ORM / ODM eller et databasebibliotek som slipper unna data eller støtter navngitte eller indekserte parameteriserte spørsmål, og tar vare på å validere brukerinndata for forventede typer. Bruk aldri JavaScript-malstrenger eller strengkonketting for å injisere verdier i spørsmål, da dette åpner applikasjonen din for et bredt spekter av sårbarheter. Alle anerkjente Node.js-datatilgangsbiblioteker (f.eks. Sequelize, Knex, mongoose) har innebygd beskyttelse mot injeksjonsangrep

Ellers: Uvalidert eller usanisert brukerinput kan føre til operatørinjeksjon når du arbeider med MongoDB for NoSQL, og hvis du ikke bruker et riktig saneringssystem eller ORM, vil det enkelt tillate SQL-injeksjonsangrep, og skape et gigantisk sårbarhet.

Les mer: Forebygging av forespørsel om injeksjon ved bruk av ORM / ODM-bibliotek

Verdsette innsatsen? Stjerner prosjektet vårt på GitHub

5. Unngå DOS-angrep ved eksplisitt å stille inn når en prosess skal krasje

TL; DR: Node-prosessen krasjer når feil ikke blir håndtert. Mange gode fremgangsmåter anbefaler til og med å avslutte, selv om en feil ble oppdaget og ble håndtert. Express, for eksempel, vil krasje på alle asynkrone feil - med mindre du pakker ruter med en fangstklausul. Dette åpner et veldig søtt angrepssted for angripere som gjenkjenner hvilke innspill som gjør at prosessen krasjer og gjentatte ganger sender den samme forespørselen. Det er ingen øyeblikkelig løsning på dette, men noen få teknikker kan dempe smertene: Varsle med kritisk alvorlighetsgrad når som helst en prosess krasjer på grunn av en ubehandlet feil, validerer inngangen og unngå å krasje prosessen på grunn av ugyldig brukerinngang, pakke alle ruter med en fangst og vurder å ikke krasje når en feil oppsto i en forespørsel (i motsetning til hva som skjer globalt)

Ellers: Dette er bare en utdannet gjetning: gitt mange Node.js-applikasjoner, hvis vi prøver å føre et tomt JSON-organ til alle POST-forespørsler - vil en håndfull applikasjoner krasje. På det tidspunktet kan vi bare gjenta å sende den samme forespørselen om å ta ned applikasjonene med letthet

6. Juster HTTP-responsoverskriftene for økt sikkerhet

TL; DR: Søknaden din skal bruke sikre overskrifter for å forhindre at angripere bruker vanlige angrep, som cross-site scripting (XSS), clickjacking og andre ondsinnede angrep. Disse kan enkelt konfigureres ved hjelp av moduler som hjelm.

Ellers: Angripere kan utføre direkte angrep på brukerne av applikasjonen din, og føre til enorme sikkerhetsproblemer

Les mer: Bruke sikre topptekster i applikasjonen din

7. Kontroller kontinuerlig og automatisk for sårbare avhengigheter

TL; DR: Med npm-økosystemet er det vanlig å ha mange avhengigheter for et prosjekt. Avhengigheter bør alltid holdes i sjakk da nye sårbarheter blir funnet. Bruk verktøy som npm audit, nsp eller snyk for å spore, overvåke og korrigere sårbare avhengigheter. Integrer disse verktøyene med CI-oppsettet slik at du får en sårbar avhengighet før den kommer til produksjon.

Ellers: En angriper kan oppdage nettrammen din og angripe alle kjente sårbarheter.

Les mer: Avhengighetssikkerhet

8. Unngå å bruke Node.js kryptobibliotek for håndtering av passord, bruk Bcrypt

TL; DR: Passord eller hemmeligheter (API-nøkler) bør lagres ved å bruke en sikker hash + salt-funksjon som bcrypt, som bør være et foretrukket valg fremfor JavaScript-implementeringen på grunn av ytelse og sikkerhetsmessige årsaker.

Ellers: Passord eller hemmeligheter som vedvarer uten å bruke en sikker funksjon er sårbare for brute-tvang og ordbokangrep som vil føre til avsløring av dem etter hvert.

Les mer: Bruk Bcrypt

9. Escape HTML, JS og CSS output

TL; DR: Utrolige data som sendes ned til nettleseren kan bli kjørt i stedet for bare å bli vist, dette blir ofte referert til som et XSS-angrep på tvers av steder. Begrens dette ved å bruke dedikerte biblioteker som eksplisitt markerer dataene som rent innhold som aldri skal kunne kjøres (dvs. koding, rømming)

Ellers: En angriper kan lagre en ondsinnet JavaScript-kode i DB-en din som deretter blir sendt som den er til de fattige klientene

Les mer: Escape output

10. Valider innkommende JSON-skjemaer

TL; DR: Valider innlasting av innkommende forespørsler og sikre at den kvalifiserer forventningene, mislykkes raskt hvis den ikke gjør det. For å unngå kjedelig valideringskoding innenfor hver rute, kan du bruke lette JSON-baserte valideringsskjemaer som jsonschema eller joi

Ellers: Din generøsitet og tillatte tilnærming øker angrepsoverflaten kraftig og oppfordrer angriperen til å prøve ut mange innspill til de finner en eller annen kombinasjon for å krasje applikasjonen

Les mer: Valider innkommende JSON-skjemaer

11. Støtt svartelistede JWT-symboler

TL; DR: Når du bruker JWT-tokens (for eksempel med Passport.js), er det som standard ingen mekanisme for å tilbakekalle tilgang fra utstedte tokens. Når du oppdager en ondsinnet brukeraktivitet, er det ingen måte å hindre dem i å få tilgang til systemet så lenge de har et gyldig symbol. Begrens dette ved å implementere en svarteliste med ikke-tillitsfulle symboler som er validert på hver forespørsel.

Ellers: Utløpte eller feilplasserte symboler kan brukes ondsinnet av en tredjepart for å få tilgang til et program og etterligne eieren av symbolet.

Les mer: Blacklisting JWTs

12. Hindre angrep mot brute-force mot autorisasjon

TL; DR: En enkel og kraftig teknikk er å begrense autorisasjonsforsøk ved å bruke to beregninger:

  1. Det første er antall påfølgende mislykkede forsøk fra samme bruker unike ID / navn og IP-adresse.
  2. Det andre er antall mislykkede forsøk fra en IP-adresse over en lengre periode. Blokkerer for eksempel en IP-adresse hvis den gjør 100 mislykkede forsøk på en dag.

Ellers: En angriper kan utstede ubegrensede automatiske passordforsøk for å få tilgang til privilegerte kontoer i et program

Les mer: Innloggingsfrekvensbegrensning

13. Kjør Node.js som ikke-root-bruker

TL; DR: Det er et vanlig scenario der Node.js kjører som en rotbruker med ubegrensede tillatelser. Dette er for eksempel standardoppførselen i Docker-containere. Det anbefales å opprette en bruker som ikke er root, og enten bake den inn i Docker-bildet (eksempler gitt nedenfor) eller kjøre prosessen på vegne av disse brukerne ved å påkalle beholderen med flagget "-u brukernavn"

Ellers: En angriper som klarer å kjøre et skript på serveren, får ubegrenset makt over den lokale maskinen (f.eks. Endre iptable og omdirigere trafikk til serveren sin)

Les mer: Kjør Node.js som ikke-root-bruker

14. Begrens størrelsen på nyttelasten ved hjelp av en omvendt proxy eller mellomvare

TL; DR: Jo større kropps nyttelast er, jo vanskeligere fungerer den enkelte tråden når du behandler den. Dette er en mulighet for angripere å bringe servere på kne uten enorme forespørsler (DOS / DDOS-angrep). Begrens dette ved å begrense kroppsstørrelsen på innkommende forespørsler på kanten (f.eks. Brannmur, ELB) eller ved å konfigurere ekspresslegeme-parser til å akseptere bare nyttelast i liten størrelse

Ellers: Søknaden din vil måtte håndtere store forespørsler, og kan ikke behandle det andre viktige arbeidet den har å utføre, noe som fører til resultatkonsekvenser og sårbarhet overfor DOS-angrep

Les mer: Begrens størrelsen på nyttelast

Få beste praksis per uke via Twitter-feeden vår

15. Unngå JavaScript-evalueringer

TL; DR: eval er ondt da det gjør det mulig å utføre en tilpasset JavaScript-kode i løpet av kjøretiden. Dette er ikke bare et ytelsesproblem, men også et viktig sikkerhetsproblem på grunn av ondsinnet JavaScript-kode som kan hentes fra brukerinndata. En annen språkfunksjon som bør unngås er ny Funksjonskonstruktør. setTimeout og setInterval skal heller ikke sendes dynamisk JavaScript-kode.

Ellers: Ondsinnet JavaScript-kode finner en vei inn i en tekst som er sendt inn i eval eller andre sanntidsevaluerende JavaScript-språkfunksjoner, og vil få full tilgang til JavaScript-tillatelser på siden. Denne sårbarheten er ofte manifestert som et XSS-angrep.

Les mer: Unngå JavaScript-evalueringer

16. Hindre at onde RegEx overbelaster kjøringen av en enkelt tråd

TL; DR: Vanlige uttrykk utgjør en virkelig trussel for JavaScript-applikasjoner for øvrig, og spesielt Node.js-plattformen, mens de er nyttige. En brukerinput for tekst å matche kan kreve en utmerket mengde CPU-sykluser for å behandle. RegEx-prosessering kan være ineffektiv i en grad at en enkelt forespørsel som validerer 10 ord kan blokkere hele hendelsesløkken i 6 sekunder og sette CPU på . Av den grunn foretrekker du tredjeparts valideringspakker som validator.js i stedet for å skrive dine egne Regex-mønstre, eller bruk sikker-regex for å oppdage sårbare regex-mønstre

Ellers: Dårlig skrevne regekser kan være mottakelige for DoS-angrep med vanlige uttrykk som vil blokkere hendelsesløkken helt. Den populære øyeblikkspakken ble for eksempel funnet sårbar med ondsinnet RegEx-bruk i november 2017

Les mer: Forhindre ondsinnet RegEx

17. Unngå lasting av moduler ved å bruke en variabel

TL; DR: Unngå å kreve / importere en annen fil med en bane som ble gitt som parameter på grunn av bekymring for at den kunne ha stammet fra brukerinput. Denne regelen kan utvides for å få tilgang til filer generelt (dvs. fs.readFile ()) eller annen sensitiv ressurstilgang med dynamiske variabler som stammer fra brukerinput. Eslint-plugin-sikkerhet linter kan fange slike mønstre og advare tidlig nok

Ellers: Ondsinnet brukerinput kan finne veien til en parameter som brukes til å kreve tuklede filer, for eksempel en tidligere opplastet fil i filsystemet, eller få tilgang til allerede eksisterende systemfiler.

Les mer: Sikker modulbelastning

18. Kjør usikker kode i en sandkasse

TL; DR: Når du får i oppgave å kjøre ekstern kode som er gitt ved kjøretid (f.eks. Plugin), bruk hvilken som helst slags "sandkasse" -utføringsmiljø som isolerer og beskytter hovedkoden mot plugin. Dette kan oppnås ved å bruke en dedikert prosess (f.eks. Cluster.fork ()), serverløse omgivelser eller dedikerte npm-pakker som fungerer som en sandkasse

Ellers: En plugin kan angripe gjennom et uendelig utvalg av alternativer som uendelige løkker, overbelastning av minne og tilgang til sensitive prosessmiljøvariabler

Les mer: Kjør usikker kode i en sandkasse

19. Vær ekstra forsiktig når du jobber med barneprosesser

TL; DR: Unngå å bruke barneprosesser når det er mulig, og validerer og desinfiser input for å dempe skallinjeksjonsangrep hvis du fortsatt må. Foretrekker å bruke child_process.execFile som per definisjon bare vil utføre en enkelt kommando med et sett attributter og ikke tillater utvidelse av shell-parameter.

Ellers: Naiv bruk av underordnede prosesser kan føre til ekstern utførelse av kommandoer eller angrep av skallinjeksjon på grunn av ondsinnet brukerinngang sendt til en usanisert systemkommando.

Les mer: Vær forsiktig når du jobber med barneprosesser

20. Skjul feildetaljer fra klienter

TL; DR: En integrert ekspressfeilhåndterer skjuler feildetaljene som standard. Imidlertid er store sjansene for at du implementerer din egen feilhåndteringslogikk med tilpassede feilobjekter (av mange ansett som en god praksis). Hvis du gjør det, må du forsikre deg om ikke å returnere hele Error-objektet til klienten, som kan inneholde noen sensitive applikasjonsdetaljer

Ellers: Sensitive applikasjonsdetaljer som serverfilstier, tredjepartsmoduler som er i bruk og andre interne arbeidsflyter i applikasjonen som kan bli utnyttet av en angriper, kan lekke ut fra informasjonen som finnes i en stakkspor

Les mer: Skjul feildetaljer fra klienter

21. Konfigurer 2FA for npm eller Garn

TL; DR: Ethvert trinn i utviklingskjeden skal beskyttes med MFA (multifaktor-autentisering), npm / Garn er en søt mulighet for angripere som kan få tak i noen utviklerens passord. Ved hjelp av utviklereegistreringsinformasjon kan angripere injisere ondsinnet kode i biblioteker som er mye installert på tvers av prosjekter og tjenester. Kanskje til og med over hele nettet hvis de blir publisert offentlig. Aktivering av 2-faktor-autentisering i npm gir angripere nesten null sjanser til å endre pakke koden.

Ellers: Har du hørt om eslint-utvikleren som passordet ble kapret?

22. Endre innstillinger for økt mellomvare

TL; DR: Hver nettramme og teknologi har sine kjente svakheter - å fortelle en angriper hvilket nettramme vi bruker er en stor hjelp for dem. Ved å bruke standardinnstillingene for midlertidige økter kan appen din blottlegges for modul- og rammespesifikke kapingsangrep på lignende måte som X-Powered-By-overskriften. Prøv å skjule alt som identifiserer og avslører teknologibunken din (f.eks. Node.js, express)

Ellers: Informasjonskapsler kan sendes over usikre tilkoblinger, og en angriper kan bruke øktidentifisering for å identifisere den underliggende rammen for webapplikasjonen, samt modulspesifikke sårbarheter

Les mer: Informasjon om cookies og økter

23. Unngå DOS-angrep ved eksplisitt å stille inn når en prosess skal krasje

TL; DR: Node-prosessen krasjer når feil ikke blir håndtert. Mange gode fremgangsmåter anbefaler til og med å avslutte, selv om en feil ble oppdaget og ble håndtert. Express, for eksempel, vil krasje på alle asynkrone feil - med mindre du pakker ruter med en fangstklausul. Dette åpner et veldig søtt angrepssted for angripere som gjenkjenner hvilke innspill som gjør at prosessen krasjer og gjentatte ganger sender den samme forespørselen. Det er ingen øyeblikkelig løsning på dette, men noen få teknikker kan dempe smertene: Varsle med kritisk alvorlighetsgrad når som helst en prosess krasjer på grunn av en ubehandlet feil, validerer inngangen og unngå å krasje prosessen på grunn av ugyldig brukerinngang, pakke alle ruter med en fangst og vurder å ikke krasje når en feil oppsto i en forespørsel (i motsetning til hva som skjer globalt)

Ellers: Dette er bare en utdannet gjetning: gitt mange Node.js-applikasjoner, hvis vi prøver å føre et tomt JSON-organ til alle POST-forespørsler - vil en håndfull applikasjoner krasje. På det tidspunktet kan vi bare gjenta å sende den samme forespørselen om å ta ned applikasjonene med letthet.

24. Hindre usikre viderekoblinger

TL; DR: Omdirigeringer som ikke validerer brukerinndata, kan gjøre det mulig for angripere å starte phishing-svindel, stjele brukeropplysninger og utføre andre ondsinnede handlinger.

Ellers: Hvis en angriper oppdager at du ikke validerer eksterne, brukerleverte innspill, kan de utnytte dette sikkerhetsproblemet ved å legge ut spesiallagde lenker på fora, sosiale medier og andre offentlige steder for å få brukere til å klikke på det.

Les mer: Hindre usikre viderekoblinger

25. Unngå å publisere hemmeligheter til npm-registeret

TL; DR: Forholdsregler bør tas for å unngå risikoen for utilsiktet publisering av hemmeligheter til offentlige npm-registre. En .npmignore-fil kan brukes til å svarteliste spesifikke filer eller mapper, eller filmatrisen i package.json kan fungere som en hviteliste.

Ellers: Prosjektets API-nøkler, passord eller andre hemmeligheter er åpne for å bli misbrukt av alle som kommer over dem, noe som kan føre til økonomisk tap, etterligning og andre risikoer.

Les mer: Unngå å publisere hemmeligheter

Verdsette innsatsen? Stjerner prosjektet vårt på GitHub

26. En liste over 40 generiske sikkerhetsråd (ikke spesifikt Node.js-relatert)

Følgende kuler er velkjente og viktige sikkerhetstiltak som bør brukes i hver applikasjon. Siden de ikke nødvendigvis er relatert til Node.js og implementert på samme måte uavhengig av applikasjonsrammeverk - inkluderer vi dem her som et vedlegg. Elementene er gruppert etter OWASP-klassifiseringen. En prøve inkluderer følgende punkter:

  • Krev MFA / 2FA for root-konto
  • Roter passord og tilgangstaster ofte, inkludert SSH-nøkler
  • Bruk sterke passordpolicyer, både for ops og brukerstyring i applikasjonen, se OWASP passordanbefaling
  • Ikke send eller distribuer med noen standardopplysninger, spesielt for administratorbrukere
  • Bruk bare standard autentiseringsmetoder som OAuth, OpenID osv. - unngå grunnleggende autentisering
  • Begrensning av autentisk hastighet: Tillat mer enn X påloggingsforsøk (inkludert gjenoppretting av passord, etc.) i løpet av Y minutter
  • Ved påloggingsfeil, ikke la brukeren vite om brukernavnet eller passordbekreftelsen mislyktes, bare returner en vanlig autorisasjonsfeil
  • Vurder å bruke et sentralisert brukeradministrasjonssystem for å unngå å administrere flere kontoer per ansatt (f.eks. GitHub, AWS, Jenkins, osv.) Og dra fordel av et kamptestet brukeradministrasjonssystem

Den komplette listen over 40 generelle sikkerhetsråd finner du i det offisielle depotet for beste praksis for Node.js!

Les mer: 40 Generelle sikkerhetsråd

Andre gode leser:

  • Node.js beste praksis - Yoni Goldberg
  • Node.js sikkerhetsoversikt - Gergely Nemeth
  • Express sikkerhetspraksis - Express tjenestemann
  • YouTube: En Node.js sikkerhets veikart - Mike Samuel

Forfattere - om oss

  • Yoni Goldberg - Node.js konsulent, som betjener kunder i USA, Europa og Israel
  • Kyle Martin - Full Stack Developer med base i New Zealand
  • Bruno Scheufler - Fullstabel nettutvikler og Node.js-entusiast
Verdsette innsatsen? Å klappe nederst (opptil 50 ganger) kan gjøre dagen vår