Applikations- och molnsäkerhet

Applikationssäkerhet

En praktisk guide till hur man bygger mjukvara som hanterar indata säkert, skyddar användare korrekt och minskar risk innan kod når produktion.

Applikationssäkerhet handlar om att identifiera och åtgärda sårbarheter i programvara innan och efter att den når produktion. I en DevSecOps-kultur vävs säkerhet in i varje fas av utvecklingscykeln istället för att läggas till som ett sista steg.

Lärandemål

Det här ska du kunna efter genomläsning.
  • Förklara de viktigaste kontrollerna på applikationsnivå som formar säker mjukvarudesign.
  • Känna igen hur indatahantering, identitetskontroller och sessionshantering påverkar risk.
  • Beskriva de vanligaste webbriskerna och de utvecklingsvanor som minskar dem.

I korthet

En snabb mental modell innan du går på djupet.
Grundkontroller
  • Indatavalidering
  • Autentisering
  • Behörighetsstyrning
Operativ risk
  • Sessioner
  • Hantering av hemligheter
  • Beroenden
Säkra vanor
  • Säkra standarder
  • Minsta privilegium
  • Granskbara ändringar

Hotmodellering

Hotmodellering innebar att systematiskt identifiera vad som kan ga fel med en applikation innan en enda rad kod skrivs. Team ritar dataflödesdiagram, förtroensgränser och ingångspunkter, och räknar sedan upp hot med hjälp av ramverk som STRIDE (Spoofing, Tampering, Repudiation, Information disclosure, Denial of service, Elevation of privilege). Resultatet är en prioriterad lista med åtgärder som styr designbeslut och testfall.

STRIDE-ramverket ger ingenjörer en strukturerad lins för varje komponent och dataflöde. För varje element frågar teamet. Kan detta förfalskas, kan data manipuleras i transit, kan en aktör förneka en handling, kan information röjas, kan tjänsten nekas, kan en användare få oavsiktliga privilegier? Varje jakande svar blir en åtgärdskandidat som spåras i backlogen.

Hotmodellering är mest värdefull när den genomförs tidigt i designfasen, innan betydande implementation börjar. Ett hot som upptäcks under designstadiet kräver bara en ändring i ett diagram, samma hot som upptäcks efter driftsättning kräver en patch, en migrering och eventuellt en incidentrespons. Team som bygger in hotmodellering i sin standarddesigngenomgång fångar de dyraste problemen vid det billigaste tillfället.

Statisk applikationssäkerhetstestning (SAST)

SAST-verktyg analyserar källkod utan att köra den och flaggar mönster kopplade till vanliga sårbarheter som SQL-injektion, XSS, osäker deserialisering och inbyggda hemligheter. Populära verktyg inkluderar Semgrep, Checkmarx, SonarQube och Bandit för Python. Att integrera SAST i en CI-pipeline innebär att varje pull request skannas automatiskt innan den slås ihop.

SAST fungerar genom att tolka källkoden till ett abstrakt syntaxträd eller kontrollflödesgraf och sedan tillämpa detektionsregler som matchar kända sårbara mönster. Anpassade regler kan rikta in sig på organisationsspecifika ramverk och föråldrade interna API:er som generiska regeluppsättningar missar. Att köra SAST vid varje incheckning ger utvecklare omedelbar återkoppling medan kontexten för deras ändring fortfarande är färsk.

Att hantera falska positiva resultat är den löpande utmaningen i ett SAST-program. Verktyg som genererar hundratals varningar per skanning leder snabbt till varningströtthet, där utvecklare ignorerar alla fynd inklusive verkliga problem. Effektiva program investerar i regelinställning, undertryckning av bekräftade falska positiva och en prioriteringsprocess som skickar verkliga fynd till rätt utvecklare.

Dynamisk applikationssäkerhetstestning (DAST)

DAST-verktyg interagerar med en körande applikation på samma sätt som en angripare, skickar konstruerade indata och inspekterar svar efter tecken på sårbarheter. OWASP ZAP och Burp Suite är vanliga DAST-verktyg. Eftersom DAST kräver ett distribuerat mål körs det vanligtvis mot en staging- eller integrationsmiljö.

DAST hittar körningssårbarheter som statisk analys inte kan nå. Autentiseringskonfigurationsfel, problem med sessionshantering, osäkra HTTP-headers, serverfel som läcker interna sökvägar och injektionssårbarheter som bara uppstår när hela stacken körs tillsammans. Det validerar applikationen som den faktiskt beter sig, inte bara som den skrevs.

En typisk DAST-pipeline använder en spindel för att upptäcka applikationsvägar, följt av en aktiv skanning som skickar attacknyttolaster till varje endpoint. Vägar som kräver autentisering eller specifika inmatningssekvenser kan missas om inte skannern konfigureras med inloggningsuppgifter och användarflöden. Att kombinera automatiserad DAST med periodisk manuell penetrationstestning täpper till detta täckningsgap.

Analys av programvarukompositioner (SCA)

Moderna applikationer beror i hög grad på öppen källkodsbibliotek. SCA-verktyg skannar beroendemanifester och låsfiler och matchar komponenter mot sårbarhetsdata som NVD och OSV. Verktyg som Snyk, Dependabot och OWASP Dependency-Check varnar team när ett direkt eller transitivt beroende har en känd sårbarhet.

Den viktigaste risken är transitiva beroenden. Ett projekt med tio direkta paket kan dra in hundratals transitiva, var och en en potentiell exponering. Log4Shell-sårbarheten (CVE-2021-44228) illustrerade detta i stor skala. Miljoner applikationer påverkades inte för att de direkt berodde på Log4j, utan för att det var ett transitivt beroende av ett ramverk de använde. Synlighet i hela beroendeträdet är inte valfri.

SCA-verktyg genererar också Software Bills of Materials (SBOM), maskinläsbara inventeringar av varje komponent i en applikation. SBOM:er möjliggör snabb triage när nya sårbarheter avslöjas. Istället för att manuellt granska varje applikation kan ett team fråga SBOM-inventeringen och omedelbart identifiera varje påverkat system. Att generera SBOM:er krävs i allt större utsträckning av statliga upphandlingspolicyer och standarder för leveranskedjans säkerhet.

Säkra kodningsprinciper

Utöver verktyg behöver utvecklare en grundläggande kunskapsbas om säker kodning. Nyckelprinciper inkluderar indatavalidering, utdatakodning, parametriserade frågor, principen om minsta behörighet och felhantering som undviker att läcka stackspår eller interna sökvägar till användare. Dessa principer adresserar grundorsakerna till de vanligaste sårbarhetskategorierna.

OWASP Top 10 är en allmänt använd taxonomi över de mest kritiska webbsårbarhetskategorierna. Att förstå injektion, bruten åtkomstkontroll, kryptografiska fel och säkerhetsmissconfiguration ger utvecklare en mental modell för att känna igen sårbara mönster innan de skriver dem. OWASP cheat sheets ger kortfattad, språkspecifik vägledning för att implementera varje åtgärd korrekt.

Program med säkerhetsambassadörer inbäddar säkerhetsmedvetna ingenjörer i varje produktteam och skapar kollegiala resurser för säkerhetsfrågor. Ambassadörer är inte grindvakter som granskar kod i efterhand, de är rådgivare som hjälper team att fatta bättre beslut under design och implementation, innan sårbarheter skapas.

Signaler att bevaka

Mönster som är värda att undersöka vidare.
  • Användarindata når affärslogik utan tydlig validering eller normalisering.
  • Åtkomstkontroller är inkonsekventa mellan routes, handlers eller tjänster.
  • Hemligheter, token eller inloggningsuppgifter förekommer i kod, loggar eller konfigurationsfiler.

FÖRDJUPNING

Grunder i säker kodning

Säker kodning innebär att skriva programvara där säkerhet behandlas som ett förstaklassigt krav jämfört med funktionalitet. Istället för att härda kod i efterhand integrerar säker kodning defensivt tänkande i varje funktion, varje indatahanterare och varje dataflöde. Målet är kod som är korrekt och säker samtidigt, inte snabb kod som lappas senare.

Grunden är att förstå applikationens förtroendemodell. Varje bit data som passerar en förtroensgräns, från en användare, ett partner-API, en meddelandekö eller en databas, måste behandlas som potentiellt fientlig tills den validerats. Att data kom från den egna databasen gör den inte säker om databasen kan innehålla värden injicerade av en tidigare angripare.

Kärnprinciperna är inte komplicerade. Validera all indata, koda all utdata för dess destinationskontext, använd parametriserade frågor för databasåtkomst, tillämpa minsta behörighet i alla resursförfrågningar, misslyckas säkert vid fel och logga aldrig känsliga värden. Dessa principer adresserar grundorsakerna till de vanligaste sårbarhetskategorierna.

Det mest ihållande misstaget är att anta att ett ramverk hanterar säkerhet automatiskt. Ramverk förhindrar många misstag men kan inte skydda mot varje felaktig användning. En utvecklare som använder ett ORM felaktigt kan ändå introducera SQL-injektion. En utvecklare som inaktiverar auto-escaping i en mallmotor kan ändå introducera XSS. Säkerhet kräver förståelse, inte bara val av rätt verktyg.

Indatavalidering

Indatavalidering är processen att verifiera att data från externa källor uppfyller förväntat format, typ, längd och intervall innan applikationen bearbetar eller lagrar den. Tillåtelselistevalidering (ibland kallad vitlistevalidering) definierar exakt vad som är acceptabelt och avvisar allt annat. Neklistervalidering försöker avvisa kända felaktiga mönster. Tillåtelselistevalidering är nästan alltid starkare.

Nästan varje injektionsangrepp utnyttjar kod som bearbetar opålitlig indata utan validering. SQL-injektion skickar databassyntax i formulärfält. Kommandoinjektion skickar skalmetakartecken. Sökvägstraversering använder sekvenser som '../' för att fly avsedda kataloger. Alla delar samma grundorsak. Extern data behandlades som pålitlig utan att kontrolleras.

Validering på serversidan är obligatorisk oavsett vilken validering på klientsidan som finns. Klientvalidering (JavaScript eller HTML-indatabegränsningar) förbättrar användarupplevelsen men ger inga säkerhetsgarantier. En angripare kan kringgå klientvalidering genom att skicka HTTP-förfrågningar direkt till servern med verktyg som curl eller Burp Suite. Om validering bara sker i webbläsaren är servern helt oskyddad.

Validering måste ske vid mottagningspunkten, innan data används i säkerhetskänsliga operationer. Ett vanligt misstag är att validera i UI-lagret men sedan skicka data genom flera tjänstlager innan det når databasen, där varje lager antar att det föregående validerade. Om ett lager vidarebefordrar ovaliderad data bryts skyddet. Validera så nära källan som möjligt och kontrollera igen vid konsumtionspunkten för högriskoperationer.

Autentisering

Autentisering är processen att verifiera att en användare, tjänst eller enhet är den den utger sig för att vara. I webbapplikationer innebär detta vanligtvis att verifiera en uppgift (lösenord, token, certifikat) mot en lagrad post. Bruten autentisering är konsekvent en av de främsta sårbarhetskategorierna i webbapplikationer eftersom konsekvenserna av misslyckande är allvarliga. En angripare som kringgår autentiseringen kan utge sig för att vara vilken användare som helst, inklusive administratörer.

Stark lösenordsbaserad autentisering kräver att lösenord lagras med en hashalgoritm designad för lösenordslagring (bcrypt, scrypt eller Argon2), inte MD5 eller osaltad SHA-1. Flöden för lösenordsåterställning måste använda tidsbegränsade tokens som skickas till en verifierad kanal. Kontobegränsning eller hastighetsbegränsning måste förhindra brute-force-angrepp.

Multifaktorautentisering (MFA) minskar dramatiskt risken för kontokompromettering. Även om ett lösenord stjäls genom nätfiske, ett dataintrång eller lösenordsåteranvändning kräver MFA att angriparen också har en andra faktor. En TOTP-kod från en autentiseringsapp, en hårdvarusäkerhetsnyckel (FIDO2/WebAuthn) eller en engångskod skickad till ett verifierat telefonnummer. Hårdvarunycklar är det starkaste alternativet eftersom de är phishing-resistenta.

Ett vanligt autentiseringsmisstag är att implementera ett lösenordsåterställningsflöde som är svagare än inloggningsflödet. Om en angripare kan återställa ett kontos lösenord med enbart e-postadressen definieras autentiseringsstyrkan av den svagaste länken. Ett annat vanligt misstag är att inte ogiltigförklara befintliga sessioner efter en lösenordsändring, vilket lämnar gamla tokens aktiva även efter att kontots uppgifter har ändrats.

Auktorisering

Auktorisering är processen att avgöra om en autentiserad identitet har tillåtelse att utföra en specifik åtgärd eller komma åt en specifik resurs. Autentisering svarar på vem du är, auktorisering svarar på vad du får göra. Bruten åtkomstkontroll är den vanligaste sårbarhetskategorin i OWASP Top 10, vilket innebär att auktoriseringsfel är vanligare och mer skadliga än någon annan sårbarhetsklass.

Rollbaserad åtkomstkontroll (RBAC) tilldelar behörigheter till roller och roller till användare. Attributbaserad åtkomstkontroll (ABAC) fattar beslut baserat på attribut hos användaren, resursen och miljön. I båda modellerna är det kritiska kravet att kontroller sker på serversidan vid varje förfrågan, inte bara en gång vid inloggning.

Osäker direkt objektreferens (IDOR) är den vanligaste åtkomstkontrollsårbarheten. Den uppstår när en applikation använder ett värde från användaren (ett numeriskt ID, ett UUID, ett filnamn) för att slå upp en resurs utan att verifiera att den begärande användaren är auktoriserad att komma åt just den posten. En angripare som märker att deras konto-ID visas i en URL kan prova att ersätta andra ID:n och kan finna att servern returnerar andras data utan någon ägarskontroll.

Ett grundläggande misstag i auktoriseringsdesign är att blanda ihop dunkelhet med åtkomstkontroll. Att gömma en administrativ endpoint bakom en lång, slumpmässig sökväg är inte auktorisering. Om URL:en någonsin upptäcks via webbläsarhistorik, felmeddelanden eller referrer-headers, ger den obegränsad åtkomst till alla som hittar den. Varje känslig endpoint måste ha en explicit auktoriseringskontroll oavsett hur svår den är att hitta.

Sessionsproblem

Sessionshantering täcker hur en applikation upprätthåller kontinuitet för en autentiserad användare över flera HTTP-förfrågningar. Eftersom HTTP är tillståndslöst utfärdar applikationer en sessionstoken efter lyckad inloggning och klienten presenterar denna token vid varje efterföljande förfrågan. Säkerheten för hela den autentiserade sessionen beror på denna token. En angripare som erhåller en giltig token har samma åtkomst som den legitima användaren utan att någonsin känna till lösenordet.

Säkra sessionstokens måste vara långa (minst 128 bitar kryptografisk slumpmässighet), genererade av en kryptografiskt säker slumptalgenerator och skickas enbart över HTTPS. Cookies som bär sessionstokens bör ha HttpOnly-flaggan (förhindrar JavaScript från att läsa cookievärdet) och Secure-flaggan (förhindrar sändning över vanlig HTTP). SameSite-attributet bör ställas in på Strict eller Lax för att minska risken för CSRF.

Sessionsfixering är ett angrepp där angriparen lurar offret att autentisera sig med en token som angriparen redan känner till. Försvaret är att alltid generera en ny sessionstoken omedelbart efter lyckad autentisering, och ersätta eventuell token som existerade före inloggning. Privilegieelevering inom en session bör också utlösa en ny token.

Att inte ogiltigförklara sessioner på serversidan vid utloggning är ett kritiskt och vanligt misstag. Om servern helt enkelt instruerar klienten att ta bort sin cookie utan att ogiltigförklara sessionsposten på serversidan förblir token giltig. En angripare som fångat token före utloggning kan fortsätta använda den. Riktig utloggning måste ogiltigförklara sessionen på servern så att token är värdelös även om en angripare besitter den.

Vanliga webbangrepp

OWASP Top 10 listar de mest kritiska webbapplikationssäkerhetsriskerna, uppdaterade periodiskt för att återspegla det aktuella hotlandskapet. 2021 års utgåva täcker. Bruten åtkomstkontroll, kryptografiska fel, injektion, osäker design, säkerhetsmissconfiguration, sårbara och föråldrade komponenter, identifierings- och autentiseringsfel, programvaru- och dataintegritetfel, brister i säkerhetsloggning och SSRF. Varje kategori delar grundorsaker och liknande motåtgärder.

Cross-Site Scripting (XSS) uppstår när en applikation inkluderar opålitlig data i en webbsida utan korrekt kodning, vilket gör att angripare kan injicera JavaScript som körs i offrets webbläsare. Lagrad XSS (där det skadliga skriptet sparas i databasen) är särskilt farlig eftersom varje användare som tittar på det drabbade innehållet angrips. Försvaret är kontextkänslig utdatakodning.

Server-Side Request Forgery (SSRF) är en sårbarhet där en angripare får servern att göra HTTP-förfrågningar till angriparkontrollerade destinationer. Detta är farligt i molnmiljöer eftersom instansmetadatatjänsten (som tillhandahåller temporära molnuppgifter) bara är åtkomlig från instansen själv. En angripare som når metadatatjänsten via SSRF kan stjäla instansens molnuppgifter.

En vanlig begreppsförvirring är att behandla XSS och CSRF som samma angrepp. XSS angriper användaren genom att injicera skadligt innehåll i sidor de tittar på. CSRF angriper servern genom att lura användarens webbläsare att göra oavsiktliga förfrågningar. XSS-försvar fokuserar på utdatakodning. CSRF-försvar fokuserar på att verifiera förfrågningens ursprung med tokens eller SameSite-cookieattributet.

Hemligheter i applikationskod

Hemligheter i applikationskod avser antimönstret att bädda in uppgifter, API-nycklar, lösenord eller kryptografiska nycklar direkt i källkod, konfigurationsfiler eller byggartefakter som checkas in i versionshantering. Detta är ett av de vanligaste och mest utnyttjade säkerhetsmistagen inom programvaruutveckling. Uppgifter inbäddade i kod hittas genom repository-skanning, intrång eller oavsiktlig publicering av repon.

Git-historikproblemet gör detta misstag svårt att återhämta sig från. Även om en utvecklare tar bort en hemlighet från den senaste incheckningen finns den kvar i git-historiken för alla med åtkomst till repositoryt. Verktyg som 'git log -S' och 'git diff' kan återskapa vilken sträng som helst som någonsin checkats in. Den enda säkra åtgärden efter att en hemlighet har checkats in är att rotera den omedelbart.

Det korrekta mönstret är att ladda hemligheter från miljön vid körning, inte från källkod. Använd miljövariabler injicerade av driftsättningssystemet, eller hämta hemligheter från ett dedikerat valv som HashiCorp Vault eller molnleverantörens hemlighetstjänst. Applikationskoden refererar till en konfigurationsnyckel, driftsättningssystemet mappar nyckeln till det faktiska hemlighetsvärdet vid körning.

Verktyg för hemlighetsskanning hittar uppgifter i versionshantering. Verktyg som Gitleaks, TruffleHog och GitHubs inbyggda hemlighetsskanning körs automatiskt vid incheckningar och varnar när mönster som matchar API-nycklar, anslutningssträngar eller privata nycklar detekteras. Att köra dessa kontroller som en pre-commit hook fångar hemligheter innan de checkas in, att köra dem i CI fångar dem som slunkit igenom.

Beroendeexponering på applikationsnivå

Beroendeexponering avser den säkerhetsrisk som introduceras av tredjepartsbibliotek, ramverk och paket som en applikation förlitar sig på. Moderna applikationer beror vanligtvis på dussintals till hundratals öppen källkodspaket, var och en med potentiella kända eller okända sårbarheter. Applikationen ärver säkerhetsstatusen för varje beroende den använder, direkt deklarerade eller dragna in transitivt.

Riskens skala blev dramatiskt tydlig med Log4Shell-sårbarheten (CVE-2021-44228) i december 2021. En enda kritisk sårbarhet i Log4j-loggningsbiblioteket påverkade miljoner applikationer världen över. Angripare utnyttjades aktivt inom timmar efter avslöjandet. Team med noggranna beroendeinventeringar identifierade och åtgärdade drabbade system på timmar, team utan synlighet spenderade dagar på att avgöra om de var påverkade.

Analys av programvarukompositioner (SCA) adresserar denna risk genom att kontinuerligt skanna hela beroendeträdet (inklusive transitiva beroenden) mot sårbarhetsdata. När en ny sårbarhet avslöjas kan SCA-verktyg omedelbart rapportera vilka applikationer som påverkas och vid vilken allvarlighetsgrad. Att integrera SCA i CI-pipelines innebär att pull requests som introducerar sårbara beroenden blockeras innan de slås ihop.

Att hålla beroenden uppdaterade kräver en strategi, inte ad-hoc manuella uppdateringar. Automatiserade uppdateringsverktyg (Dependabot, Renovate) öppnar pull requests när nyare versioner finns tillgängliga. Att låsa exakta beroendeversioner med låsfiler säkerställer reproducerbara byggen men kräver aktiv uppdateringshantering. Den farligaste positionen är olåsta, oövervakade beroenden som tyst halkar efter på säkerhetspatchar.