Programmering

Tretten regler for utvikling av sikre Java-applikasjoner

Sikkerhet er en av de mest komplekse, brede og viktige aspektene ved programvareutvikling. Programvaresikkerhet blir også ofte oversett, eller forenklet til bare noen få mindre justeringer på slutten av utviklingssyklusen. Vi kan se resultatene i den årlige listen over store datasikkerhetsbrudd, som i 2019 utgjorde over 3 milliarder eksponerte poster. Hvis det kan skje med Capital One, kan det skje med deg.

Den gode nyheten er at Java er en langvarig utviklingsplattform med mange innebygde sikkerhetsfunksjoner. Java Security-pakken har gjennomgått intensiv kamptesting, og oppdateres ofte for nye sikkerhetsproblemer. Den nyere Java EE Security API, utgitt i september 2017, adresserer sårbarheter i sky- og mikrotjenestearkitekturer. Java-økosystemet inneholder også et bredt spekter av verktøy for profilering og rapportering av sikkerhetsproblemer.

Men selv med en solid utviklingsplattform er det viktig å være årvåken. Applikasjonsutvikling er et komplekst oppdrag, og sårbarheter kan gjemme seg i bakgrunnsstøyen. Du bør tenke på sikkerhet i alle ledd i applikasjonsutviklingen, fra språkfunksjoner på klassenivå til autorisasjon av API-endepunkt.

Følgende grunnregler gir et godt grunnlag for å bygge sikrere Java-applikasjoner.

Java-sikkerhetsregel nr. 1: Skriv ren, sterk Java-kode

Sårbarheter elsker å gjemme seg i kompleksitet, så hold koden din så enkel som mulig uten å ofre funksjonaliteten. Ved å bruke velprøvde designprinsipper som DRY (ikke gjenta deg selv) vil det hjelpe deg å skrive kode som er lettere å gjennomgå for problemer.

Utsett alltid så lite informasjon som mulig i koden din. Å skjule implementeringsdetaljer støtter kode som er både vedlikeholdbar og sikker. Disse tre tipsene vil gå langt mot å skrive sikker Java-kode:

  • Benytt deg av Java tilgangsmodifikatorer godt. Å vite hvordan du skal erklære forskjellige tilgangsnivåer for klasser, metoder og deres attributter, vil langt på vei beskytte koden din. Alt som kan gjøres privat, bør være privat.
  • Unngå refleksjon og introspeksjon. Det er noen tilfeller der slike avanserte teknikker er fortjent, men for det meste bør du unngå dem. Å bruke refleksjon eliminerer sterk skriving, noe som kan introdusere svake punkter og ustabilitet i koden din. Å sammenligne klassenavn som strenger er utsatt for feil og kan lett føre til kollisjon mellom navneområdet.
  • Definer alltid minst mulig API og grensesnittflater. Koble komponenter og få dem til å samhandle på tvers av det minste området mulig. Selv om ett område av søknaden din er infisert av et brudd, vil andre være trygge.

Java-sikkerhetsregel nr.2: Unngå serialisering

Dette er et annet kodetips, men det er viktig nok til å være en egen regel. Serialisering tar en ekstern inngang og forvandler den til et fullt utstyrt objekt. Den dispenserer med konstruktører og tilgangsmodifikatorer, og gjør det mulig for en strøm av ukjent data å bli kjørende kode i JVM. Som et resultat er Java-serialisering dypt og iboende usikker.

Slutten på Java-serialisering

Hvis du ikke har hørt det, har Oracle langsiktige planer om å fjerne serialisering fra Java. Mark Reinhold, sjefarkitekt for Java-plattformsgruppen i Oracle, har sagt at han mener en tredjedel eller flere av alle Java-sårbarheter involverer serialisering.

Så mye som mulig, unngå serialisering / deserialisering i Java-koden. I stedet bør du vurdere å bruke et serieiseringsformat som JSON eller YAML. Utsett aldri et ubeskyttet nettverksendepunkt som mottar og virker på en serialiseringsstrøm. Dette er ingenting annet enn en velkomstmatte for kaos.

Java-sikkerhetsregel nr. 3: Utsett aldri ukryptert legitimasjon eller PII

Det er vanskelig å tro, men denne feilen som kan unngås forårsaker smerte år etter år.

Når en bruker skriver inn et passord i nettleseren, sendes det som ren tekst til serveren din. Det burde være siste gang det ser dagens lys. Du kryptere passordet via en enveis cypher før du fortsetter det til databasen, og gjør det igjen når du sammenligner med den verdien.

Reglene for passord gjelder all personlig identifiserbar informasjon (PII): kredittkort, personnummer osv. All personlig informasjon som er betrodd søknaden din, skal behandles med høyeste grad av forsiktighet.

Ukryptert legitimasjon eller PII i en database er et gapende sikkerhetshull som venter på at en angriper skal oppdage. På samme måte må du aldri skrive rå legitimasjon til en logg, eller på annen måte overføre til fil eller nettverk. I stedet lager du en saltet hash for passordene dine. Sørg for å gjøre undersøkelser og bruk en anbefalt hashingalgoritme.

Å hoppe ned til regel nr. 4: bruk alltid et bibliotek for kryptering; ikke rull din egen.

Java-sikkerhetsregel nr. 4: Bruk kjente og testede biblioteker

Fest øynene dine på dette spørsmålet og svaret om å rulle din egen sikkerhetsalgoritme. Tl; dr leksjonen er: bruk kjente, pålitelige biblioteker og rammer når det er mulig. Dette gjelder over hele spekteret, fra passordhashing til REST API-autorisasjon.

Heldigvis har Java og dets økosystem ryggen din her. For sikkerhets skyld er Spring Security de facto-standarden. Det tilbyr et bredt spekter av alternativer og fleksibilitet til å passe med hvilken som helst apparkitektur, og den inneholder en rekke sikkerhetsmetoder.

Ditt første instinkt i å takle sikkerhet bør være å gjøre undersøkelser. Undersøk beste praksis, og undersøk deretter hvilket bibliotek som vil implementere denne fremgangsmåten for deg. Hvis du for eksempel ser på å bruke JSON Web Tokens til å administrere autentisering og autorisasjon, kan du se på Java-biblioteket som innkapsler JWT, og deretter lære å integrere det i Spring Security.

Selv ved å bruke et pålitelig verktøy er det ganske enkelt å bungle autorisasjon og autentisering. Sørg for å bevege deg sakte og dobbeltsjekke alt du gjør.

Java-sikkerhetsregel nr. 5: Vær paranoid om ekstern inngang

Enten det kommer fra en bruker som skriver inn et skjema, en datalager eller et eksternt API, stoler aldri på ekstern inngang.

SQL-injeksjon og cross-site scripting (XSS) er bare de mest kjente angrepene som kan skyldes feil håndtering av eksterne innganger. Et mindre kjent eksempel - en av mange - er "billion latter-angrepet", der XML-enhetsutvidelse kan forårsake et Denial of Service-angrep.

Hver gang du mottar innspill, bør det kontrolleres og sanitiseres. Dette gjelder spesielt alt som kan presenteres for et annet verktøy eller system for behandling. For eksempel, hvis noe kan avvikle som et argument for en OS-kommandolinje: pass opp!

En spesiell og velkjent forekomst er SQL-injeksjon, som dekkes i neste regel.

Java-sikkerhetsregel nr. 6: Bruk alltid forberedte utsagn til å håndtere SQL-parametere

Hver gang du bygger opp en SQL-setning, risikerer du å interpolere et fragment av kjørbar kode.

Å vite dette, det er en god praksis å alltid bruk klassen java.sql.PreparedStatement for å opprette SQL. Lignende fasiliteter finnes for NoSQL-butikker som MongoDB. Hvis du bruker et ORM-lag, vil implementeringen bruke det PreparedStatements for deg under panseret.

Java-sikkerhetsregel nr. 7: Ikke avslør implementering via feilmeldinger

Feilmeldinger i produksjonen kan være en fruktbar kilde til informasjon for angripere. Stakkspor kan spesielt avsløre informasjon om teknologien du bruker og hvordan du bruker den. Unngå å avsløre stakkspor til sluttbrukere.

Mislykkede påloggingsvarsler faller også inn i denne kategorien. Det er generelt akseptert at en feilmelding skal gis som "Innlogging mislyktes" kontra "Fant ikke den brukeren" eller "Feil passord." Tilby så lite hjelp til potensielt skumle brukere som mulig.

Ideelt sett bør feilmeldinger ikke avsløre den underliggende teknologibakken for applikasjonen din. Hold informasjonen så ugjennomsiktig som mulig.

Java-sikkerhetsregel 8: Hold sikkerhetsutgivelser oppdatert

Fra og med 2019 har Oracle implementert en ny lisensiering og utgivelsesplan for Java. Dessverre for utviklere gjør den nye utgivelseskadensen ikke ting enklere. Ikke desto mindre er du ansvarlig for å ofte sjekke om sikkerhetsoppdateringer og bruke dem på JRE og JDK.

Sørg for at du vet hvilke kritiske oppdateringer som er tilgjengelige ved å sjekke Oracle-hjemmesiden for sikkerhetsvarsler. Hvert kvartal leverer Oracle en automatisk oppdatering av oppdateringen for den nåværende LTS-versjonen (langvarig støtte) av Java. Problemet er at oppdateringen bare er tilgjengelig hvis du betaler for en Java-støttelisens.

Hvis organisasjonen din betaler for en slik lisens, følg ruten for automatisk oppdatering. Hvis ikke, bruker du sannsynligvis OpenJDK, og du må lappe deg selv. I dette tilfellet kan du bruke den binære oppdateringen, eller du kan bare erstatte din eksisterende OpenJDK-installasjon med den nyeste versjonen. Alternativt kan du bruke en kommersielt støttet OpenJDK som Azul's Zulu Enterprise.

Trenger du alle sikkerhetsoppdateringer?

Hvis du ser nøye på sikkerhetsvarslene, kan det hende du ikke trenger et gitt sett med oppdateringer. For eksempel utgivelsen fra januar 2020 vises å være en kritisk Java-oppdatering; en nøye lesing viser imidlertid at oppdateringen bare lapper hull i Java applet-sikkerhet, og ikke påvirker Java-servere.

Java-sikkerhetsregel nr. 9: Se etter avhengighetsproblemer

Det er mange verktøy tilgjengelig for automatisk å skanne kodebasen og avhengighet for sårbarheter. Alt du trenger å gjøre er å bruke dem.

OWASP, Open Web Application Security Project, er en organisasjon dedikert til å forbedre kodesikkerhet. OWASPs liste over pålitelige automatiserte kodeskanningsverktøy av høy kvalitet inkluderer flere Java-orienterte verktøy.

Sjekk kodebasen din regelmessig, men hold også øye med avhengighet fra tredjepart. Angripere retter seg mot både åpne og lukkede kildebiblioteker. Se etter oppdateringer til avhengighetene dine, og oppdater systemet ditt når nye sikkerhetsoppdateringer blir utgitt.

Java-sikkerhetsregel nr. 10: Overvåke og logge brukeraktivitet

Selv et enkelt brute-force-angrep kan lykkes hvis du ikke aktivt overvåker søknaden din. Bruk verktøy for overvåking og logging for å holde øye med apphelsen.

Hvis du vil være overbevist om hvorfor overvåking er viktig, er det bare å sitte og se TCP-pakker på applikasjonslytteporten. Du vil se alle slags aktiviteter, langt utover enkle brukerinteraksjoner. Noe av denne aktiviteten vil være roboter og onde mennesker som søker etter sårbarheter.

Du bør logge og overvåke mislykkede påloggingsforsøk og bruke mottiltak for å forhindre eksterne klienter fra å angripe ustraffet.

Overvåking kan varsle deg om uforklarlige pigger, og logging kan hjelpe til med å løse hva som gikk galt etter et angrep. Java-økosystemet inkluderer et vell av kommersielle og åpen kildekodeløsninger for logging og overvåking.

Java-sikkerhetsregel nr. 11: Se opp for Denial of Service (DoS) -angrep

Når du behandler potensielt dyre ressurser eller foretar potensielt dyre operasjoner, bør du beskytte deg mot løpende ressursbruk.

Oracle opprettholder en liste over potensielle vektorer for denne typen problemer i Secure Coding Guidelines for Java SE document, under overskriften "Denial Of Service".

I utgangspunktet, når som helst du går for å utføre en kostbar operasjon, som å pakke ut en komprimert fil, bør du overvåke for eksploderende ressursbruk. Ikke stol på filmanifestene. Stol bare på det faktiske forbruket på disken eller i minnet, overvåk det og beskytt deg mot overdreven servering.

Tilsvarende er det viktig i noen behandlingen å se etter uventede evig-løkker. Hvis en sløyfe er mistenksom, legg til en vakt som sikrer at sløyfen gjør fremgang og kortslut den hvis den ser ut til å ha blitt zombie.

Java-sikkerhetsregel nr. 12: Vurder å bruke Java-sikkerhetsbehandling

Java har en sikkerhetsbehandling som kan brukes til å begrense ressursene en kjørende prosess har tilgang til. Det kan isolere programmet med hensyn til disk, minne, nettverk og JVM-tilgang. Å begrense disse kravene til appen din reduserer muligheten for mulig skade fra et angrep. Slik isolasjon kan også være upraktisk, og det er derfor Sikkerhetssjef er ikke aktivert som standard.

Du må selv bestemme om du skal jobbe rundt Sikkerhetssjefsterke meninger er verdt det ekstra beskyttelseslaget for applikasjonene dine. Se Oracle-dokumentene for å lære mer om syntaksen og funksjonene til Java-sikkerhetsbehandling.

Java-sikkerhetsregel nr. 13: Vurder å bruke en ekstern skytentifiseringstjeneste

Noen applikasjoner må ganske enkelt eie brukerdataene sine; for resten kan en skytjenesteleverandør være fornuftig.

Søk deg rundt, så finner du en rekke leverandører av skygodkjenning. Fordelen med en slik tjeneste er at leverandøren er ansvarlig for å sikre sensitive brukerdata, ikke deg. På den annen side øker kompleksiteten i bedriftsarkitekturen din ved å legge til en autentiseringstjeneste. Noen løsninger, som FireBase Authentication, inkluderer SDKer for integrering på tvers av bunken.

Konklusjon

Jeg har presentert 13 regler for utvikling av sikrere Java-applikasjoner. Disse reglene er prøvde og sanne, men den største regelen av alt er dette: vær mistenksom. Alltid tilnærming programvareutvikling med varsomhet og et sikkerhetsinnstilt syn. Se etter sårbarheter i koden din, dra nytte av Java-sikkerhets-API-ene og pakkene, og bruk tredjepartsverktøy for å overvåke og logge koden din for sikkerhetsproblemer.

Her er tre gode ressurser på høyt nivå for å holde deg oppdatert på det stadig skiftende Java-sikkerhetslandskapet:

  • OWASP Topp 10
  • CWE Topp 25
  • Oracles retningslinjer for sikker kode

Denne historien, "Tretten regler for utvikling av sikre Java-applikasjoner" ble opprinnelig utgitt av JavaWorld.

$config[zx-auto] not found$config[zx-overlay] not found