Programmering

Tretten regler til udvikling af sikre Java-applikationer

Sikkerhed er et af de mest komplekse, brede og vigtige aspekter af softwareudvikling. Softwaresikkerhed overses også ofte eller overforenkles til blot nogle få mindre justeringer i slutningen af ​​udviklingscyklussen. Vi kan se resultaterne på den årlige liste over større datasikkerhedsbrud, som i 2019 beløb sig til over 3 milliarder eksponerede poster. Hvis det kan ske med Capital One, kan det ske for dig.

Den gode nyhed er, at Java er en langvarig udviklingsplatform med mange indbyggede sikkerhedsfunktioner. Java Security-pakken har gennemgået en intensiv kamptest og opdateres ofte for nye sikkerhedssårbarheder. Den nyere Java EE Security API, der blev frigivet i september 2017, adresserer sårbarheder i sky- og mikroservicearkitekturer. Java-økosystemet indeholder også en lang række værktøjer til profilering og rapportering af sikkerhedsproblemer.

Men selv med en solid udviklingsplatform er det vigtigt at være opmærksom. Applikationsudvikling er en kompleks opgave, og sårbarheder kan skjule sig i baggrundsstøjen. Du bør overveje sikkerhed på hvert trin i applikationsudvikling, fra sprogfunktioner på klasseniveau til API-slutpunkttilladelse.

Følgende grundregler giver et godt fundament til opbygning af mere sikre Java-applikationer.

Java-sikkerhedsregel nr. 1: Skriv ren, stærk Java-kode

Sårbarheder elsker at gemme sig i kompleksitet, så hold din kode så enkel som muligt uden at ofre funktionaliteten. Brug af gennemprøvede designprincipper som TØR (gentag ikke dig selv) hjælper dig med at skrive kode, der er lettere at gennemgå for problemer.

Udsæt altid så lidt information som muligt i din kode. At skjule implementeringsoplysninger understøtter kode, der er både vedligeholdelig og sikker. Disse tre tip vil gå langt i retning af at skrive sikker Java-kode:

  • Gør god brug af Java's adgangsmodifikatorer. At vide, hvordan man deklarerer forskellige adgangsniveauer for klasser, metoder og deres attributter, vil være langt for at beskytte din kode. Alt, hvad der kan gøres privat, skal være privat.
  • Undgå refleksion og introspektion. Der er nogle tilfælde, hvor sådanne avancerede teknikker fortjenes, men for det meste bør du undgå dem. Brug af refleksion eliminerer stærk skrivning, som kan introducere svage punkter og ustabilitet i din kode. Sammenligning af klassenavne som strenge er fejlbehæftet og kan let føre til navneområdet kollision.
  • Definer altid den mindste mulige API og interface overflader. Afkobling af komponenter og få dem til at interagere på tværs af det mindste mulige område. Selvom et område af din ansøgning er inficeret af en overtrædelse, vil andre være sikre.

Java-sikkerhedsregel nr. 2: Undgå serialisering

Dette er et andet kodningstip, men det er vigtigt nok til at være en egen regel. Serialisering tager en fjernindgang og omdanner den til et fuldt udstyret objekt. Det undgår konstruktører og adgangsmodifikatorer og giver mulighed for, at en strøm af ukendte data bliver kørende kode i JVM. Som et resultat er Java-serialisering dybt og i sagens natur usikker.

Slutningen af ​​Java-serialisering

Hvis du ikke har hørt det, har Oracle langsigtede planer om at fjerne serialisering fra Java. Mark Reinhold, chefarkitekt for Java-platformgruppen i Oracle, har sagt, at han mener, at en tredjedel eller flere af alle Java-sårbarheder involverer serialisering.

Undgå så vidt muligt serialisering / deserialisering i din Java-kode. I stedet overvej at bruge et serialiseringsformat som JSON eller YAML. Udsæt aldrig nogensinde et ubeskyttet netværksendepunkt, der modtager og virker på en serialiseringsstrøm. Dette er intet andet end en velkomstmåtte til kaos.

Java-sikkerhedsregel nr. 3: Udsæt aldrig ukrypterede legitimationsoplysninger eller PII

Det er svært at tro, men denne undgåelige fejl forårsager smerte år efter år.

Når en bruger indtaster en adgangskode i browseren, sendes den som almindelig tekst til din server. Det skulle være sidste gang det ser dagens lys. Du skal kryptere adgangskoden via en envejs-cypher, før du vedvarer den til databasen, og gør den derefter igen, når du sammenligner med den værdi.

Reglerne for adgangskoder gælder for alle personligt identificerbare oplysninger (PII): kreditkort, personnumre osv. Alle personlige oplysninger, der overlades til din ansøgning, skal behandles med den største omhu.

Ukrypterede legitimationsoplysninger eller PII i en database er et gapende sikkerhedshul, der venter på, at en angriber opdager. På samme måde skal du aldrig skrive rå legitimationsoplysninger til en log eller på anden måde sende til fil eller netværk. Opret i stedet en saltet hash til dine adgangskoder. Sørg for at undersøge og bruge en anbefalet hashingalgoritme.

Hop ned til regel nr. 4: brug altid et bibliotek til kryptering; rul ikke din egen.

Java-sikkerhedsregel nr. 4: Brug kendte og testede biblioteker

Feast dine øjne på dette spørgsmål og svar om at rulle din egen sikkerhedsalgoritme. Tl; dr-lektionen er: brug kendte, pålidelige biblioteker og rammer, når det er muligt. Dette gælder på tværs af spektret, fra adgangskodeshash til REST API-godkendelse.

Heldigvis har Java og dets økosystem din ryg her. For applikationssikkerhed er Spring Security de facto-standarden. Det tilbyder en bred vifte af muligheder og fleksibilitet, der passer til enhver apparkitektur, og den indeholder en række sikkerhedstilgange.

Dit første instinkt til at tackle sikkerhed bør være at lave din forskning. Undersøg bedste praksis, og undersøg derefter, hvilket bibliotek der implementerer disse fremgangsmåder for dig. For eksempel, hvis du ser på at bruge JSON Web Tokens til at styre godkendelse og autorisation, skal du kigge på Java-biblioteket, der indkapsler JWT, og derefter lære at integrere det i Spring Security.

Selv ved hjælp af et pålideligt værktøj er det ret nemt at bungle godkendelse og godkendelse. Sørg for at bevæge dig langsomt og dobbelttjekke alt, hvad du laver.

Java-sikkerhedsregel nr. 5: Vær paranoide med ekstern input

Uanset om det kommer fra en bruger, der skriver i en formular, en datalager eller en ekstern API, har du aldrig tillid til eksternt input.

SQL-injektion og cross-site scripting (XSS) er bare de mest almindeligt kendte angreb, der kan skyldes forkert håndtering af eksternt input. Et mindre kendt eksempel - et af mange - er "billion-grinangrebet", hvor XML-enhedsudvidelse kan forårsage et Denial of Service-angreb.

Hver gang du modtager input, skal det kontrolleres og saneres. Dette gælder især for alt, der kan præsenteres for et andet værktøj eller system til behandling. For eksempel, hvis noget kunne afvikles som et argument for en OS-kommandolinje: pas på!

En særlig og velkendt forekomst er SQL-injektion, som er dækket af den næste regel.

Java-sikkerhedsregel nr. 6: Brug altid forberedte udsagn til at håndtere SQL-parametre

Hver gang du opbygger en SQL-sætning, risikerer du at interpolere et fragment af eksekverbar kode.

At vide dette er det en god praksis at altid brug klassen java.sql.PreparedStatement til at oprette SQL. Lignende faciliteter findes for NoSQL-butikker som MongoDB. Hvis du bruger et ORM-lag, vil implementeringen bruge det PreparedStatements til dig under hætten.

Java-sikkerhedsregel nr. 7: Afslør ikke implementering via fejlmeddelelser

Fejlmeddelelser i produktionen kan være en frugtbar kilde til information for angribere. Stakspor kan især afsløre oplysninger om den teknologi, du bruger, og hvordan du bruger den. Undgå at afsløre stakspor til slutbrugere.

Alarmer med mislykket login falder også ind i denne kategori. Det accepteres generelt, at en fejlmeddelelse skal gives som "Login mislykkedes" versus "Fandt ikke den bruger" eller "Forkert adgangskode." Tilby så lidt hjælp til potentielt dårlige brugere som muligt.

Ideelt set bør fejlmeddelelser ikke afsløre den underliggende teknologistak til din applikation. Hold disse oplysninger så uigennemsigtige som muligt.

Java-sikkerhedsregel nr. 8: Hold sikkerhedsudgivelser opdaterede

Fra og med 2019 har Oracle implementeret en ny licensordning og frigivelsesplan for Java. Desværre for udviklere gør den nye frigivelseskadens ikke ting lettere. Ikke desto mindre er du ansvarlig for ofte at kontrollere sikkerhedsopdateringer og anvende dem på din JRE og JDK.

Sørg for at vide, hvilke kritiske programrettelser der er tilgængelige, ved regelmæssigt at kontrollere Oracle-hjemmesiden for sikkerhedsadvarsler. Hvert kvartal leverer Oracle en automatisk opdatering af patch til den nuværende LTS (langvarig support) frigivelse af Java. Problemet er, at programrettelsen kun er tilgængelig, hvis du betaler for en Java-supportlicens.

Hvis din organisation betaler for en sådan licens, skal du følge ruten til automatisk opdatering. Hvis ikke, bruger du sandsynligvis OpenJDK, og du skal selv lappe. I dette tilfælde kan du anvende den binære patch, eller du kan blot erstatte din eksisterende OpenJDK-installation med den nyeste version. Alternativt kan du bruge en kommercielt understøttet OpenJDK som Azuls Zulu Enterprise.

Har du brug for hver sikkerhedspatch?

Hvis du ser sikkerhedsalarmerne nøje, kan du muligvis finde ud af, at du ikke har brug for et givet sæt opdateringer. For eksempel frigivelsen fra januar 2020 kommer til syne at være en kritisk Java-opdatering en nøje læsning viser imidlertid, at opdateringen kun lapper huller i Java-applets sikkerhed og ikke påvirker Java-servere.

Java-sikkerhedsregel nr. 9: Se efter afhængighedssårbarheder

Der er mange tilgængelige værktøjer til automatisk at scanne din codebase og afhængigheder for sårbarheder. Alt du skal gøre er at bruge dem.

OWASP, Open Web Application Security Project, er en organisation dedikeret til at forbedre kodesikkerhed. OWASPs liste over pålidelige automatiserede kodescanningsværktøjer i høj kvalitet indeholder flere Java-orienterede værktøjer.

Tjek din codebase regelmæssigt, men hold også øje med tredjepartsafhængigheder. Angribere målretter mod både open- og closed source-biblioteker. Hold øje med opdateringer til dine afhængigheder, og opdater dit system, når nye sikkerhedsrettelser frigives.

Java-sikkerhedsregel nr. 10: Overvåg og log brugeraktivitet

Selv et simpelt brute-force-angreb kan være vellykket, hvis du ikke aktivt overvåger din applikation. Brug overvågnings- og logningsværktøjer til at holde øje med appens sundhed.

Hvis du gerne vil være overbevist om, hvorfor overvågning er vigtig, skal du bare sidde og se TCP-pakker på din applikations lytteport. Du kan se alle slags aktiviteter, langt ud over enkle brugerinteraktioner. Noget af denne aktivitet vil være bots og onde handlinger, der scanner efter sårbarheder.

Du skal logge og overvåge for mislykkede loginforsøg og implementere modforanstaltninger for at forhindre fjernklienter i at angribe med straffrihed.

Overvågning kan advare dig om uforklarlige spidser, og logning kan hjælpe med at opklare, hvad der gik galt efter et angreb. Java-økosystemet inkluderer et væld af kommercielle og open source-løsninger til logning og overvågning.

Java-sikkerhedsregel nr. 11: Pas på angreb på Denial of Service (DoS)

Hver gang du behandler potentielt dyre ressourcer eller foretager potentielt dyre operationer, skal du beskytte dig mod løbende ressourceforbrug.

Oracle vedligeholder en liste over potentielle vektorer til denne type problemer i sine Secure Coding Guidelines for Java SE-dokument under overskriften "Denial Of Service".

Dybest set, når som helst du går for at udføre en dyr operation, som at pakke en komprimeret fil ud, skal du overvåge for eksploderende ressourceforbrug. Stol ikke på filmanifester. Stol kun på det faktiske forbrug på disken eller i hukommelsen, overvåg det og vær opmærksom på at overføre serveren til knæ.

Tilsvarende er det i nogle processer vigtigt at se efter uventede evigt-løkker. Hvis der er mistanke om en sløjfe, skal du tilføje en vagt, der sikrer, at sløjfen gør fremskridt, og kortslutte den, hvis den ser ud til at være blevet zombie.

Java-sikkerhedsregel nr. 12: Overvej at bruge Java-sikkerhedsadministratoren

Java har en sikkerhedsadministrator, der kan bruges til at begrænse de ressourcer, en kørende proces har adgang til. Det kan isolere programmet med hensyn til disk, hukommelse, netværk og JVM-adgang. At indsnævre disse krav til din app reducerer fodaftrykket for mulig skade fra et angreb. Sådan isolering kan også være ubelejlig, hvorfor det er SecurityManager er ikke aktiveret som standard.

Du bliver selv nødt til at beslutte, om du skal arbejde rundt SecurityManagerDe stærke meninger er det ekstra beskyttelseslag til dine applikationer værd. Se Oracle-dokumenterne for at lære mere om Java-sikkerhedsadministratorens syntaks og muligheder.

Java-sikkerhedsregel nr. 13: Overvej at bruge en ekstern cloud-godkendelsestjeneste

Nogle applikationer skal simpelthen eje deres brugerdata; for resten kunne en cloud-tjenesteudbyder give mening.

Søg rundt, og du finder en række leverandører af cloudgodkendelse. Fordelen ved en sådan tjeneste er, at udbyderen er ansvarlig for at sikre følsomme brugerdata, ikke dig. På den anden side øger kompleksiteten i din virksomhedsarkitektur ved at tilføje en godkendelsestjeneste. Nogle løsninger, som FireBase Authentication, inkluderer SDK'er til integration over hele stakken.

Konklusion

Jeg har præsenteret 13 regler til udvikling af mere sikre Java-applikationer. Disse regler er prøvet og sandt, men den største regel af alt er dette: vær mistænksom. Tilgå altid softwareudvikling med varsomhed og et sikkerhedsindstillet perspektiv. Se efter sårbarheder i din kode, udnyt Java-sikkerheds-API'erne og -pakkerne, og brug tredjepartsværktøjer til at overvåge og logge din kode med henblik på sikkerhedsproblemer.

Her er tre gode ressourcer på højt niveau for at holde dig ajour med det stadigt skiftende Java-sikkerhedslandskab:

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

Denne historie, "Tretten regler til udvikling af sikre Java-applikationer" blev oprindeligt udgivet af JavaWorld.