Hur SAST åtgärdar de 10 största sårbarheterna i OWASP

Statisk kodanalys för säkerhet: Hur SAST åtgärdar de 10 största sårbarheterna i OWASP

Säkerhetsproblem är lättare att förebygga än att åtgärda. En SQL-injektionsbrist som upptäcks i en kodgranskning kostar minuter att korrigera. Samma brist som upptäcks efter ett intrång kostar veckor av incidenthantering, myndighetsutredning och åtgärd, plus eventuell data som extraherats däremellan. Statisk kodanalys är disciplinen att hitta dessa problem innan koden körs, genom att undersöka källkodsstruktur, dataflöde och mönster mot kända sårbarhetssignaturer. Tillämpad systematiskt omvandlar den säkerhet från en reaktiv praxis till en inbyggd egenskap i utvecklingsprocessen.

OWASP Top 10 är den auktoritativa katalogen över de mest kritiska säkerhetsriskerna för webbapplikationer, uppdaterad av Open Web Application Security Project baserat på verkliga sårbarhetsdata från tusentals applikationer. Varje punkt på listan kan detekteras, i varierande grad, av statiska analysverktyg. Den här guiden kartlägger varje OWASP-kategori utifrån vad statisk analys kan hitta, visar det sårbara kodmönstret och dess säkra motsvarighet och förklarar vilka verktyg som tillämpar varje teknik.

Hitta injektionen innan angripare gör det

SMART TS XL spårar sårbarheter från JavaScript API:er via Java-tjänster till COBOL-backends.

Mer information

Vad är statisk applikationssäkerhetstestning (SAST)?

Statisk applikationssäkerhetstestning, SAST, analyserar källkod, bytekod eller binärkod utan att programmet körs. Analysen undersöker hur data flödar genom applikationen, vilka säkerhetskänsliga operationer som data når och om någon sökväg från en extern inmatning (användarinmatning, HTTP-parametrar, filinnehåll, miljövariabler) leder till en farlig operation (databasfråga, systemkommando, HTML-utmatning, kryptografisk funktion) utan lämplig validering eller sanering.

SAST är ett lager i ett komplett program för applikationssäkerhet. Att förstå var det passar in kräver att man jämför det med alternativen:

TillvägagångssättNär det körsVad den hittarVad den saknar
SAST (Statisk)Före exekvering, på källkodSårbarheter på kodnivå, injektionsmönster, kryptografiskt missbruk, hårdkodade hemligheterRuntime-sårbarheter, konfigurationsproblem i distributionen
DAST (Dynamisk)Mot en pågående applikationKörningsbeteende, autentiseringsfel, problem med serverkonfigurationKodnivåmönster utlöstes inte under testning
SCA (Programvarukompositionsanalys)På beroende manifesterarKända CVE:er i tredjepartsbibliotekSårbarheter i anpassad kod
IAST (Interaktiv)Under testkörning med instrumenteringRuntime-dataflöden med hög noggrannhetKräver ett program som körs, långsammare feedback

SAST ger den tidigaste feedbacken, den körs på kod som ännu inte har driftsatts, i CI/CD-pipelinen eller ens i IDE:n, innan sårbarheten någonsin når en testmiljö. Denna tidighet är dess primära säkerhetsvärde.

Vilka typer av hot kan statisk kodanalys mildra?

Detta är en av de mest sökta frågorna om SAST. Det direkta svaret:

Statisk kodanalys kan mildra hot som manifesterar sig i källkodsmönster : injektionssårbarheter (SQL, kommandon, XSS), kryptografisk missbruk, hårdkodade autentiseringsuppgifter, osäkra autentiseringsimplementeringar, bruten åtkomstkontroll i kodlogik och dataintegritetsfel. Den kan inte mildra hot som uppstår från runtime-konfiguration, nätverkstopologi eller infrastrukturinstallation, de som kräver DAST, penetrationstestning eller säkerhetsskanning av infrastrukturen.

Statisk analys kontra dynamisk analys för OWASP-täckning

Dynamisk analys (DAST) och statisk analys (SAST) hittar olika delmängder av OWASP-sårbarheter. Ingen av dem täcker allt. OWASP Web Security Testing Guide (WSTG) är metodramverket för dynamisk testning; SAST-verktyg som CodeQL, Semgrep och SonarQube adresserar källkodslagret.

OWASP Topp 10-kategoriSAST-täckningDAST-täckning
Trasig åtkomstkontrollDelvisa luckor i kodlogikBra beteendetestning vid körning
Kryptografiska misslyckandenStark algoritmdetekteringSvag, svår att observera utifrån
InjektionStark, smutsavvisande analysStark, aktiv nyttolasttestning
Osäker designDelvis mönsterdetekteringSvag, kräver designkunskap
Felaktig konfiguration av säkerhetDelvis, konfiguration i kodStark testning i realtid
Sårbara komponenterSvag, SCA är bättreSvag, SCA är bättre
AutentiseringsfelDelvisa, hårdkodade krediter, svaga mönsterStark sessions- och autentiseringstestning
Fel i dataintegritetenPartiella avserialiseringsmönsterSvag, svår att upptäcka utifrån
LoggningsfelDelvisa, saknade loggsatserSvag, svårobserverad frånvaro
SSRFStark, avföring mot HTTP-anropStark, aktiv förfrågningstestning

Slutsatsen: SAST och DAST kompletterar varandra. För maximal OWASP-täckning, kör båda. För budgetbegränsade team, börja från noll, med SAST först, ger det den snabbaste utvecklarfeedbacken och den bredaste injektionstäckningen.

OWASP Topp 10: Vad statisk analys visar och hur

A01, Trasig åtkomstkontroll

Bruten åtkomstkontroll är den största OWASP-risken. Statisk analys åtgärdar manifestationer på kodnivå: saknade auktoriseringskontroller av funktioner och slutpunkter, objektreferenser som exponerar interna ID:n utan validering och hårdkodade rolltilldelningar som kringgår avsedda behörighetsstrukturer.

Vad statisk analys upptäcker: Metoder som hanterar känsliga operationer utan motsvarande auktoriseringskontroll; direkta objektreferenser där objekt-ID:t kommer från användarinmatning utan åtkomstvalidering; tvångsbaserade bläddringsmönster där autentiserat tillstånd kontrolleras men objektägande inte.

Java

// Vulnerable: no ownership check -- any authenticated user can access any order
@GetMapping("/orders/{orderId}")
public Order getOrder(@PathVariable Long orderId) {
    return orderRepository.findById(orderId).orElseThrow();
}

// Secure: verify the order belongs to the requesting user
@GetMapping("/orders/{orderId}")
public Order getOrder(@PathVariable Long orderId,
                      @AuthenticationPrincipal UserDetails user) {
    Order order = orderRepository.findById(orderId).orElseThrow();
    if (!order.getOwnerId().equals(user.getUserId())) {
        throw new AccessDeniedException("Order does not belong to requesting user");
    }
    return order;
}

Vad statisk analys inte kan upptäcka: Fel vid åtkomstkontroll vid körning där logiken är korrekt men data som används för att fatta beslutet är komprometterade. DAST och penetrationstester behövs för dessa.

A02, Kryptografiska fel

Svag kryptografi kan tillförlitligt detekteras genom statisk analys eftersom de sårbara mönstren, MD5, SHA-1, DES, ECB-läge, hårdkodade nycklar, är lexiskt identifierbara i källkoden.

pytonorm

# Vulnerable: MD5 for password hashing (broken algorithm)
import hashlib
password_hash = hashlib.md5(password.encode()).hexdigest()

# Vulnerable: hardcoded encryption key
KEY = b"mysecretkey12345"
cipher = AES.new(KEY, AES.MODE_ECB)  # ECB mode also vulnerable

# Secure: bcrypt for passwords, environment-sourced keys
import bcrypt, os
password_hash = bcrypt.hashpw(password.encode(), bcrypt.gensalt(rounds=12))

# Secure: AES-GCM with environment-sourced key
import os
from cryptography.hazmat.primitives.ciphers.aead import AESGCM
key = os.environ["ENCRYPTION_KEY"].encode()
aesgcm = AESGCM(key)

Flagga för statiska analysregler: MD5/SHA-1 för säkerhetskänsliga ändamål, DES/3DES/RC4/ECB-läge, hårdkodade kryptografiska nycklar och hemligheter, HTTP istället för HTTPS för överföring av känslig data och inaktiverad certifikatverifiering (verify=False i Python-förfrågningar, setHostnameVerifier(ALLOW_ALL_HOSTNAME_VERIFIER) i Java).

A03, Injektion

Injektion, SQL, OS-kommandon, LDAP, XSS och mallinjektion är den kategori där interprocedurell taintanalys ger sitt mest direkta värde. Sårbarheten kräver spårning av otillförlitlig inmatning från dess källa genom funktionsanrop till en farlig sink.

JavaScript

// Vulnerable: direct string interpolation in SQL (SQL injection)
app.get('/users', async (req, res) => {
    const name = req.query.name;
    const result = await db.query(`SELECT * FROM users WHERE name = '${name}'`);
    res.json(result.rows);
});

// Secure: parameterized query
app.get('/users', async (req, res) => {
    const name = req.query.name;
    const result = await db.query('SELECT * FROM users WHERE name = $1', [name]);
    res.json(result.rows);
});

php

// Vulnerable: unescaped output (XSS)
echo "Welcome, " . $_GET['username'];

// Secure: context-appropriate escaping
echo "Welcome, " . htmlspecialchars($_GET['username'], ENT_QUOTES, 'UTF-8');

csharp

// Vulnerable: command injection in C#
var process = new Process();
process.StartInfo.FileName = "cmd.exe";
process.StartInfo.Arguments = "/c " + userInput;
process.Start();

// Secure: avoid shell interpretation, validate and whitelist inputs
var allowedCommands = new HashSet<string> { "report", "export" };
if (!allowedCommands.Contains(userInput))
    throw new ArgumentException("Invalid command");

Verktyg som utför interprocedurell taintanalys för injektion: CodeQL (mest exakt), Semgrep med taint-läge, Snyk Code, SonarQube med säkerhetsregler.

A04, Osäker design

Osäker design är den svåraste OWASP-kategorin för statisk analys eftersom den handlar om arkitektoniska beslut snarare än kodmönster. Statisk analys kan visa symptomen:

Saknad logik för hastighetsbegränsande funktioner på autentiseringsslutpunkter, avsaknad av kontoutlåsning efter misslyckade försök, affärslogik som hoppar över valideringssteg och funktioner som utför privilegierade åtgärder utan granskningsloggning. Dessa kan detekteras som saknade mönster, statisk analys som rapporterar om vad som saknas snarare än vad som finns.

Vissa SAST-verktyg stöder anpassade regler som kan koda organisationens säkerhetsdesignkrav: varje kontrollmetod måste anropa en auktoriseringsfunktion, varje databasskrivning måste föregås av inmatningsvalidering och varje externt API-anrop måste använda en timeout. Dessa anpassade regler omvandlar designkrav till verkställbara kodbegränsningar.

A05, Felaktig säkerhetskonfiguration

Säkerhetsfelkonfiguration i kod inkluderar: inaktiverade säkerhetsfunktioner, tillåtande CORS-rubriker, saknade säkerhetssvarsrubriker, felsökningsläge aktiverat i produktion och utförliga felmeddelanden som exponerar stackspårningar.

pytonorm

# Vulnerable: Flask debug mode enables interactive debugger in production
app = Flask(__name__)
app.run(debug=True)  # exposes console access if error occurs

# Vulnerable: overly permissive CORS
from flask_cors import CORS
CORS(app, origins="*")  # allows any origin

# Secure: environment-controlled debug, restricted CORS
import os
debug_mode = os.environ.get("FLASK_DEBUG", "false").lower() == "true"
CORS(app, origins=os.environ.get("ALLOWED_ORIGINS", "").split(","))
app.run(debug=debug_mode)

Flagga för statiska analysregler: felsökningsläge inställt på True i källkod, CORS-ursprung med jokertecken, saknade säkerhetsrubriker i HTTP-svarskonfigurationer, inaktiverad SSL-certifikatverifiering och standardautentiseringsuppgifter i konfigurationsfiler.

A06, Sårbara och föråldrade komponenter

Denna kategori behandlas främst av Software Composition Analysis (SCA) snarare än traditionell SAST. SCA-skanningar package.json, pom.xml, requirements.txtoch liknande manifest mot sårbarhetsdatabaser (National Vulnerability Database, GitHub Advisory Database).

SAST bidrar genom att identifiera föråldrad API-användning, anrop till biblioteksfunktioner som har ersatts på grund av säkerhetsbrister eller direkt användning av sårbara mönster som inte ens uppdaterade bibliotek längre rekommenderar.

Verktyg specifikt för A06: npm audit, pip-audit, snyk test, OWASP Dependency-Check, GitHub Dependabot och Mend (tidigare WhiteSource).

A07, Identifierings- och autentiseringsfel

Statisk analys hittar anti-mönster för autentisering på kodnivå: hårdkodade lösenord, svag lösenordsvalidering, sessionstokens genererade med icke-kryptografisk slumpmässighet, ogiltigförklaring av saknad session vid utloggning och JWT-implementeringar som accepterar none algoritm.

JavaScript

// Vulnerable: JWT accepting 'none' algorithm -- allows signature bypass
const decoded = jwt.verify(token, secret, { algorithms: ['HS256', 'none'] });

// Vulnerable: hardcoded admin credentials
if (username === 'admin' && password === 'admin123') {
    grantAccess();
}

// Secure: algorithm whitelist, no hardcoded credentials
const decoded = jwt.verify(token, process.env.JWT_SECRET, {
    algorithms: ['HS256']  // explicit allowlist only
});

csharp

// Vulnerable: weak random for session token generation in C#
var sessionToken = new Random().Next().ToString();

// Secure: cryptographically secure random
using var rng = RandomNumberGenerator.Create();
var bytes = new byte[32];
rng.GetBytes(bytes);
var sessionToken = Convert.ToBase64String(bytes);

A08, Programvaru- och dataintegritetsfel

Denna kategori omfattar osäker avserialisering och overifierade programuppdateringar. Statisk analys detekterar: Java ObjectInputStream avserialisering av data från opålitliga källor, Python pickle.loads() på externa data, PHP unserialize() med användarstyrd inmatning och YAML-parsers som använder osäkra laddare.

pytonorm

# Vulnerable: pickle deserialization of untrusted data
import pickle
data = pickle.loads(request.data)  # arbitrary code execution risk

# Vulnerable: unsafe YAML loader
import yaml
config = yaml.load(user_input)  # yaml.load without Loader is unsafe

# Secure: safe alternatives
import json
data = json.loads(request.data)  # JSON cannot execute code

import yaml
config = yaml.safe_load(user_input)  # safe_load disables arbitrary object creation

A09, Fel vid säkerhetsloggning och övervakning

Loggningsfel kan detekteras genom statisk analys som frånvarande mönster: känsliga operationer, autentiseringshändelser, åtkomstkontrollbeslut, datamodifieringar, som sker utan tillhörande loggsatser. Statiska analysregler kan kräva att vissa funktionsanrop alltid sker samtidigt som anrop för granskningsloggar.

Vad statisk analys flaggar: loggning av lösenord eller tokens (loggning av känsliga data är också en sårbarhet), undantagshanterare som tyst sväljer fel utan loggning och fångar block som loggar det råa undantagsmeddelandet (som kan innehålla känsliga data).

Java

// Vulnerable: swallowed exception, no logging
try {
    authenticateUser(username, password);
} catch (Exception e) {
    // silent failure -- no log, no audit trail
}

// Vulnerable: logging sensitive data
log.info("User logged in with password: " + password);

// Secure: log the event, not the credential
try {
    authenticateUser(username, password);
    auditLog.info("Authentication success for user: {}", username);
} catch (AuthenticationException e) {
    auditLog.warn("Authentication failure for user: {}", username);
    throw e;  // do not swallow
}

A10, Server-Side Request Forgery (SSRF)

SSRF är ett starkt argument för interprocedurell taintanalys. Sårbarheten kräver spårning av användarstyrd inmatning fram till en HTTP-förfrågan, ofta genom flera funktionsanrop. Ett verktyg som bara analyserar enskilda funktioner kan inte upptäcka SSRF när URL-konstruktionen och HTTP-anropet finns i olika funktioner.

pytonorm

# Vulnerable: user-controlled URL in HTTP request (SSRF)
import requests

def fetch_resource(url):
    return requests.get(url).content  # no validation

def api_endpoint(request):
    target = request.json().get("url")    # attacker controls this
    return fetch_resource(target)          # SSRF across function boundary

# Secure: allowlist validation before making the request
from urllib.parse import urlparse

ALLOWED_HOSTS = {"api.internal.example.com", "cdn.example.com"}

def fetch_resource(url: str) -> bytes:
    parsed = urlparse(url)
    if parsed.hostname not in ALLOWED_HOSTS:
        raise ValueError(f"URL host not allowed: {parsed.hostname}")
    return requests.get(url, timeout=5).content

Verktyg för statisk kodanalys för OWASP-säkerhet

Tabellen nedan kartlägger de viktigaste SAST-verktygen till de OWASP-kategorier de adresserar mest effektivt:

VerktygetPrimära språkOWASP-styrkorTillvägagångssätt
CodeQLJava, JS/TS, Python, C/C++, Go, RubyA03 Injektion, A10 SSRF (djup färgning)Interprocedurell semantisk analys
Semgrep30+ språkA03, A02, A07 (mönsterbaserat + smutsläge)Mönstermatchning + ytlig färgskala
Snyk kodJava, JS/TS, Python, C#A03, A07, A08ML-baserad smutsanalys
soundQube30+ språkA02, A03, A05, A07, A09Regelbaserat + dataflöde
checkmarx30+ språkFullständig OWASP-täckningInterprocedurell besvär
Vera kodJava, .NET, JS, PHPFullständig OWASP-täckningBytekod + taint-analys
OWASP ZAPSpråkagnostiskA01, A05, A07 (körtid)DAST, dynamisk testning
SMART TS XLCOBOL, JCL, Java, Python, RPG, SQLSpråköverskridande fläckar, risk för beroendeKorsspråklig strukturell + besudlad

Hur SMART TS XL Tar upp säkerhet i företagskodbaser

Företagssäkerhetsprogram står inför en utmaning som enspråkiga SAST-verktyg inte kan lösa: attackytan spänner över flera språk. En webbapplikation kan acceptera användarinmatning i JavaScript, bearbeta den i Java och skicka den genom en meddelandekö till ett COBOL-program som kör SQL mot en DB2-databas. Injektionssårbarheten finns över fyra språkgränser. Ingen enskild språkskanner ser hela sökvägen för smittspridning.

SMART TS XLÄr statisk kodanalys täcker alla språk i denna kedja samtidigt. När otillförlitlig inmatning flödar från en JavaScript API-hanterare genom en Java-tjänst till ett COBOL-program som konstruerar en dynamisk SQL-fråga, SMART TS XL spårar den vägen över hela den språkövergripande anropsgrafen, samma interprocedurella smittspårning som CodeQL tillämpar i Java, tillämpad över Java, COBOL och SQL tillsammans.

Funktionen för mappning av applikationsberoende ger en säkerhetsrelevant bild av vilka komponenter i systemet som interagerar med externa ingångar, vilka som når privilegierade operationer och hur systemets kompletta attackyta faktiskt ser ut. Denna arkitektoniska säkerhetsvy är grunden för hotmodellering, du kan inte modellera hot mot ett system vars struktur du inte förstår.

Effektanalysfunktionen används för säkerhetsåtgärder: när en sårbarhet hittas i en komponent identifierar effektanalysen alla andra komponenter som är beroende av den sårbara, och avgränsar åtgärdens omfattning noggrant innan någon kod ändras. För stora äldre kodbaser där ett COBOL-program med en säkerhetsbrist ingår i hundratals andra program, är det skillnaden mellan en hanterad åtgärd och en kaskadliknande incident att känna till hela åtgärdsomfattningen innan man börjar.

För organisationer som hanterar äldre modernisering program är säkerhetsanalys av den äldre kodbasen en förutsättning, inte en eftertanke. Att migrera sårbara COBOL-program till Java producerar sårbara Java-program. SMART TS XLs säkerhetsanalys säkerställer att sårbarheterna identifieras och åtgärdas som en del av moderniseringsprocessen, och inte upptäcks i det migrerade systemet.

Integrering av SAST i utvecklingslivscykeln

Statisk säkerhetsanalys ger sitt maximala värde när den körs vid beslutsfattandet, där kod skrivs och granskas, inte efter att den har driftsatts.

I IDE: SonarLint, Snyks IDE-tillägg och CodeQLs VS Code-tillägg visar resultat inbäddade när utvecklare skriver kod. En SQL-injektionsflagga som visas i det ögonblick en utvecklare skriver in det sårbara mönstret, vilket tar sekunder att åtgärda.

I pull-förfrågningar: SAST integrerat i GitHub Actions, GitLab CI eller Jenkins körs på varje pull-förfrågan och publicerar fynd som kommentarer i kodgranskningen. Utvecklaren ser fyndet i sitt sammanhang, tillsammans med koden som orsakade det.

Som en kvalitetsgrind: SonarQubes kvalitetsgrindsmodell blockerar sammanslagningar när nya kritiska säkerhetshotspots introduceras. Detta gör säkerhet inte till ett valfritt granskningssteg utan ett strukturellt krav i sammanslagningsprocessen.

Schemalagt: Djup interprocedural analys, CodeQL, Checkmarx, fullständiga Semgrep-regeluppsättningar, är vanligtvis för långsam för exekvering per commit men körs varje natt eller vecka på huvudgrenen och hittar sårbarheter som kräver fullständig anropsgrafanalys för att upptäckas.

Det lagerbaserade tillvägagångssättet, snabba mönsterbaserade regler i IDE:n och vid commits, djupgående taint-analys vid pull requests och nattliga, ger både den omedelbarhet som utvecklare behöver och den noggrannhet som säkerhetsprogrammen kräver.