SQL Injection i mobilutveckling: vad det är, attackmetoder och skydd

Författare: IT Sectr Publicerad: 2026-04-06 Lästid: 9 min

SQL Injection — en typ av attack mot applikationens databas där angriparen injicerar skadlig SQL-kod i frågeparametrar och får obehörig åtkomst till data eller möjlighet att ändra dem. Enligt uppgifter från OWASP (2025) är SQL Injection fortfarande en av de kritiska sårbarheterna som kan leda till fullständig kompromettering av databasen. Injektion av SQL-kod gör det möjligt för angriparen att läsa, ändra och ta bort poster, och i vissa fall — få åtkomst till serverns operativsystem.

Huvudpunkter

  • SQL Injection — injicering av SQL-kod via användarparametrar som ändrar logiken i databasfrågan
  • Parametrisering av frågor — den huvudsakliga skyddsmetoden: separering av SQL-kod från data med prepared statements
  • Attacktyper — klassisk injektion (via WHERE), Blind SQLi (logiska slutsatser), UNION-based (läsning av andra tabeller)
  • Error-based SQLi — utvinning av data via databasens felmeddelanden
  • ORM-ramverk — minskar risken för SQLi vid korrekt användning men eliminerar den inte helt

Vad är SQL Injection?

SQL Injection är en sårbarhet som uppstår när en applikation skapar en SQL-fråga genom strängkonkatenering med användardata. Angriparen skickar en speciellt konstruerad sträng till frågeparametern som ändrar strukturen på SQL-kommandot. Istället för att vara data blir den inmatade strängen en del av SQL-koden, vilket gör att angriparen kan utföra godtyckliga frågor mot databasen. Enligt Verizon Data Breach Report (2025) finns SQL Injection i 8% av alla undersökta dataläckor.

Varför är SQL Injection fortfarande aktuellt?

Trots att sårbarheten är känd (första omnämnanden — slutet av 1990-talet) förekommer SQL Injection i moderna applikationer. Orsaken — mänsklig faktor: utvecklare tillåter strängkonkatenering i koden, äldre kod omfaktoriseras inte och ORM-ramverk används felaktigt (t.ex. råa frågor med substituering av värden via strängar). Enligt uppgifter från Veracode (2026) innehåller cirka 14% av alla skannade applikationer minst en SQLi-sårbarhet.

Vad kan angriparen göra?

En lyckad SQL Injection ger angriparen ett brett spektrum av möjligheter: läsning av alla tabeller i databasen, inklusive lösenordshashar och personuppgifter; ändring och borttagning av poster; utförande av administrativa operationer (DROP TABLE, TRUNCATE); i vissa konfigurationer — fjärrexekvering av kommandon via xp_cmdshell (MSSQL) eller INTO OUTFILE (MySQL). Konsekvenserna sträcker sig från läckage av användardata till fullständig förlust av kontroll över systemet.

Typer av SQL-injektioner

SQL-injektioner klassificeras efter metoden för att extrahera data från databasen. Valet av metod beror på hur applikationen bearbetar frågeresultat och felmeddelanden. OWASP-klassificering skiljer på tre huvudtyper: In-band (data extraheras via samma kanal), Inferential/Blind (logiska slutsatser) och Out-of-band (data överförs via en annan kanal).

TypMetod för dataextraheringKomplexitetFrekvens
In-band (klassisk)Direkt via frågeresultatetLågHög
Blind SQLiLogiska slutsatser baserat på serversvarHögMedel
Out-of-bandVia extern kanal (DNS, HTTP)MedelLåg

In-band SQL Injection (klassisk)

Den vanligaste typen. Angriparen injicerar SQL-kod i frågeparametern och resultatet av injektionen syns direkt i serverns svar. Två undertyper: Error-based (via databasens felmeddelanden) och UNION-based (via UNION SELECT-operatorn). Error-based använder information från felmeddelanden, till exempel ett MySQL-syntaxfel som kan avslöja tabellnamnet eller frågestrukturen. UNION-based gör det möjligt att kombinera resultaten från en legitim fråga med data från andra databastabeller.

Blind SQL Injection (blind)

Används när applikationen inte visar frågeresultat eller felmeddelanden. Angriparen ställer frågor av typen "ja/nej" genom att skicka frågor med logiska villkor och analysera skillnaden i serverns svar (t.ex. svarstid eller sidinnehåll). Time-based Blind SQLi använder en fördröjningsfunktion (SLEEP, WAITFOR DELAY) för att bekräfta villkor — om sidan laddas längre är villkoret sant. Denna metod är mycket långsam — att extrahera en enda post kan ta timmar.

python
# Exempel på Blind SQL Injection (time-based)
# Om SQLi är sårbar utförs SLEEP(2) under villkor
import requests
import time

payload = "' OR IF(SUBSTRING((SELECT password FROM users LIMIT 1),1,1)='a',SLEEP(2),0) -- "
url = "http://example.com/user?id=1" + payload

start = time.time()
response = requests.get(url)
elapsed = time.time() - start

# Om svaret kom efter >2 sekunder — första bokstaven i lösenordet är 'a'
print(f"Time: {elapsed:.2f}s - First letter is 'a'" if elapsed > 2 else "First letter is not 'a'")

Out-of-band SQL Injection

Data överförs inte via HTTP-svaret utan via alternativa kanaler: DNS-frågor, HTTP-förfrågningar till en extern server, SMTP. Används när applikationen inte returnerar frågeresultat och inte visar fel. MySQL stöder funktionen LOAD_FILE(), som kan initiera en DNS-fråga, och MSSQL — xp_dirtree för att skicka data till en fjärr-SMB-server. Out-of-band SQL Injection är effektivt men kräver ytterligare konfiguration på angriparens server och närvaro av specifika databasfunktioner.

Hur fungerar SQL-injektion?

Mekanismen för SQL Injection bygger på att SQL använder citattecken för strängliteral. Om applikationen substituerar användarinmatning direkt i SQL-frågan utan escaping, kan angriparen "stänga" strängen och lägga till godtycklig SQL-kod. Till exempel i frågan SELECT * FROM users WHERE name = '$input' omvandlar substitueringen ' OR '1'='1 frågan till SELECT * FROM users WHERE name = '' OR '1'='1', vilket returnerar alla användare.

Klassiskt exempel: kringgående av autentisering

Betrakta ett inloggningsformulär med frågan SELECT * FROM users WHERE username = '$user' AND password = '$pass'. Om angriparen anger i användarnamnsfältet admin' -- och lämnar lösenordet tomt, blir den resulterande frågan SELECT * FROM users WHERE username = 'admin' -- ' AND password = ''. Tecknen -- kommenterar resten av frågan och villkoret för lösenordskontroll inaktiveras. Servern returnerar posten för användaren admin och angriparen loggar in utan att känna till lösenordet.

python
# Exempel på SQL Injection — kringgående av autentisering
# SÅRBAR KOD: direkt strängkonkatenering
def login_vulnerable(username, password):
    query = f"SELECT * FROM users WHERE username='{username}' AND password='{password}'"
    cursor.execute(query)
    return cursor.fetchone() is not None

# username = "admin' --" upphäver lösenordskontrollen
# SÄKER VERSION: parametriserad fråga
def login_secure(username, password):
    query = "SELECT * FROM users WHERE username = %s AND password = %s"
    cursor.execute(query, (username, password))
    return cursor.fetchone() is not None

UNION-based: läsning av andra tabeller

Operatorn UNION SELECT gör det möjligt att kombinera resultaten från två SELECT-frågor. Om angriparen hittar en sårbar parameter lägger han till UNION SELECT med en fråga från en annan tabell. Till exempel: ' UNION SELECT username, password FROM admins --. Villkor för framgång — antalet kolumner i båda frågorna måste matcha. Antalet kolumner bestäms via ORDER BY (substituering av ' ORDER BY 1--, sedan 2, 3... tills fel). När angriparen känner till antalet kolumner substituerar han UNION SELECT med samma antal fält.

SQL Injection i mobilapplikationer

Mobilapplikationer stöter på SQL Injection både på serversidan (API) och på klientsidan — i lokala databaser (SQLite, Realm). Även om risken för server-SQLi i mobilt API liknar webbapplikationer, skapar lokal databas en extra vektor. Om applikationen lagrar data i SQLite och utför frågor med strängkonkatenering, kan skadlig data som kommit in i den lokala databasen via API orsaka SQLi vid efterföljande bearbetning.

SQL Injection i SQLite på Android/iOS

Den lokala SQLite-databasen på enheten är också sårbar för SQL Injection om applikationen skapar frågor genom strängkonkatenering. Content Providers på Android och Core Data på iOS använder parametrisering som standard, men råa frågor kräver utvecklarens uppmärksamhet. SQLite stöder inte flera frågor via semikolon, vilket begränsar angriparens möjligheter men skyddar inte mot läsning av data via WHERE-villkor. Använd alltid selectionArgs i Android och NSPredicate med parametrar i iOS.

SQL Injection via mobilapplikationens API

API:et som mobilapplikationen ansluter till är lika sårbart som vilken webbserver som helst. Mobilutvecklare tror ofta att SQLi bara är ett backend-problem, men sårbarheten uppstår på API-endpoint-nivå som tar emot parametrar från klienten. Ansvarsfördelning skyddar inte: om backend-utvecklaren glömde att parametrisera frågan blir användarens mobilapplikation en attackvektor. Kräv att backend använder ORM eller prepared statements.

kotlin
// Exempel på SQL Injection i lokal SQLite på Android
// SÅRBAR KOD: direkt konkatenering
fun getUserVulnerable(db: SQLiteDatabase, userId: String): Cursor {
    return db.rawQuery(
        "SELECT * FROM users WHERE id = $userId", null
    )
}

// SÄKER VERSION: parametrisering via selectionArgs
fun getUserSecure(db: SQLiteDatabase, userId: String): Cursor {
    return db.rawQuery(
        "SELECT * FROM users WHERE id = ?",
        arrayOf(userId)
    )
}

Metoder för att förebygga SQL-injektioner

Skydd mot SQL Injection bygger på en enkel princip: lita aldrig på användarinmatning i SQL-frågor. Den enda pålitliga metoden är parametrisering av frågor (prepared statements), där SQL-kod och data skickas separat. Alla andra metoder — escaping, validering, WAF — är extra skyddslager men ersätter inte parametrisering. Enligt uppgifter från OWASP (2025) förhindrar parametrisering 100% av SQL Injection-attackerna.

Prepared Statements (parametriserade frågor)

När prepared statements används kompileras SQL-frågan först av databasservern utan data, och sedan skickas parametervärdena separat. Databasen behandlar parametrar som data, inte som exekverbar kod. Även om angriparen skickar ' OR '1'='1 tolkar databasen detta som ett strängvärde, inte som SQL-kod. Prepared statements stöds av alla moderna språk och ramverk: PDO i PHP, PreparedStatement i Java, cursor.execute i Python.

ORM-ramverk och Query Builders

Moderna ORM (Hibernate, Entity Framework, SQLAlchemy, Room) använder automatiskt parametrisering när frågor utförs, om inte utvecklaren går över till råa frågor. ORM skyddar dock inte fullständigt: konstruktioner som @Query(value = "SELECT * FROM users WHERE name = :name", nativeQuery = true) i JPA kräver att parametrar skickas via namngivna parametrar, inte via konkatenering. Query Builders (Knex, jOOQ) parametriserar också frågor som standard om inte råa metoder används.

Strängescaping (rekommenderas inte som primär metod)

Escaping av specialtecken (mysql_real_escape_string) — en föråldrad metod som inte skyddar mot alla typer av SQL Injection. Problemet: escaping beror på kodningen och kan kringgås med flerbyte-kodningar (t.ex. GBK i asiatiska system). Använd escaping endast i äldre kod där parametrisering inte är möjlig, och alltid i kombination med strikt validering av inmatningsdatatyp.

MetodEffektivitetRekommendation
Prepared Statements100%Obligatoriskt för alla frågor
ORM (korrekt användning)99%Rekommenderas
Strängescaping70% (beror på kodning)Endast äldre kod
Inmatningsvalidering (vitlista)50% (endast för siffror)Extra
WAF (Web Application Firewall)60%Extra

Principen om minsta behörighet för databasen

Applikationens konto bör ha minimalt nödvändiga rättigheter: SELECT, INSERT, UPDATE, DELETE — endast på tabeller som applikationen verkligen behöver. Förbjud användning av DROP, TRUNCATE, CREATE för applikationskontot. Detta begränsar skadan även vid en lyckad SQL Injection: angriparen kan inte ta bort tabeller eller utföra administrativa operationer.

Verktyg för att upptäcka SQL-injektioner

Regelbunden testning för SQL Injection bör vara en del av pipelinen för säker utveckling. Kombinationen av statisk analys, dynamisk skanning och manuell penetrationstestning ger bäst resultat. Enligt Synopsys Cybersecurity Report (2025) hittar automatiska skannrar upp till 70% av SQLi-sårbarheterna, men komplexa Blind-attacker kräver manuell testning.

  • sqlmap — det populäraste verktyget för automatisk upptäckt och exploatering av SQL Injection
  • OWASP ZAP — gratis DAST-skanner med moduler för aktiv SQLi-skanning
  • Burp Suite Scanner — professionellt verktyg med automatisk upptäckt av SQL Injection
  • SonarQube — statisk kodanalys för sårbarheter, inklusive SQLi-mönster
  • CodeQL — semantisk kodanalys för att hitta SQL-injektioner i källkod

För mobilapplikationer är analys av lokal SQLite också viktigt: kontrollera alla rawQuery-anrop, ContentProvider-frågor och Room-frågor med rawQuery. Verktyg: Android Studio Lint (upptäcker SQLi i SQLite), MobSF (Mobile Security Framework) för automatisk statisk och dynamisk analys av APK/IPA. Det rekommenderas också att testa API-endpoints via sqlmap med proxyavlyssning av mobilapplikationstrafik.

Vanliga frågor

Vad är skillnaden mellan SQL Injection och NoSQL Injection?

SQL Injection attackerar relationsdatabaser via SQL-frågor. NoSQL Injection påverkar icke-relationella databaser (MongoDB, Couchbase) via deras frågeoperatorer ($gte, $ne, $where). I MongoDB är injektion möjlig om applikationen skapar ett BSON-dokument från en JSON-sträng. Skyddsmekanismerna är likartade: parametrisering och typvalidering.

Hur upptäcker jag SQL Injection i koden själv?

Hitta alla ställen där SQL-frågor skapas via strängkonkatenering med användardata. Leta efter mönster som "SELECT ... WHERE id = " + userId eller f"UPDATE ... SET name = '{name}'". Varje sådan sträng är en potentiell SQL-injektion. Ersätt alla med parametriserade frågor eller prepared statements.

Skyddar ORM automatiskt mot SQL Injection?

ORM-ramverk skyddar automatiskt endast om du använder deras Query Builder-metoder och namngivna parametrar. Om du använder råa frågor (nativeQuery i JPA, rawQuery i Room) fungerar inte skyddet — du måste skicka parametrar via förberedda uttryck, inte via strängkonkatenering.

Vad är Second-Order SQL Injection?

Second-Order SQL Injection är en attack där skadlig data lagras i databasen som säker men sedan används i en annan fråga utan escaping. Till exempel registrerar sig angriparen med användarnamnet ' OR '1'='1. Data lagras som en sträng — vid registrering sker ingen attack. Men om en annan fråga substituerar användarnamnet i SQL utan parametrisering aktiveras injektionen.

Kan NoSQL Injection vara farligare än SQL Injection?

NoSQL Injection är potentiellt farligare på grund av lägre medvetenhet hos utvecklare. Utvecklare känner till SQL Injection och de flesta använder ORM, men få känner till NoSQL Injection. I MongoDB kan en felaktigt formulerad fråga returnera alla dokument i samlingen. Skydd — samma prepared statements (BSON-parametrisering) och strikt validering av inmatningsdata.

Sammanfattning

  • SQL Injection — attack genom injicering av SQL-kod via oescapade användarparametrar i databasfrågor
  • Huvudtyper — In-band (klassisk), Blind (blind, tidsbaserad), Out-of-band (via extern kanal)
  • Parametrisering av frågor — den enda 100% pålitliga skyddsmetoden mot SQL Injection
  • Myten om ORM — ORM skyddar endast med inbyggda metoder, råa frågor med konkatenering är fortfarande sårbara
  • Principen om minsta behörighet — begränsning av databaskontots rättigheter minimerar skadan vid en lyckad attack
  • Regelbunden testning — sqlmap, OWASP ZAP, SonarQube bör vara en del av CI/CD-pipelinen
  • Lokal SQLite — mobilapplikationer bör också parametrisera frågor till den lokala databasen

Vi utvecklar en mobil applikation nyckelfärdigt

IT Sectr skapar iOS- och Android-applikationer för startups och företag sedan 2017. Vi ger dig råd och föreslår den bästa lösningen.

Diskutera projektet

Läs också