SQL Injection in Mobile Development: What It Is, Attack Methods, and Protection

Author: IT Sectr Published: 2026-04-06 Reading time: 9 min

SQL Injection is a type of database attack where an attacker injects malicious SQL code into query parameters, gaining unauthorized access to data or the ability to modify it. According to OWASP (2025), SQL Injection remains one of the critical vulnerabilities capable of leading to complete database compromise. SQL code injection allows an attacker to read, modify, and delete records, and in some cases, gain access to the server's operating system.

Key Takeaways

  • SQL Injection — injecting SQL code through user parameters, altering the database query logic
  • Query Parameterization — the primary defense method: separating SQL code from data using prepared statements
  • Attack Types — classic injection (via WHERE), Blind SQLi (logical inferences), UNION-based (reading other tables)
  • Error-based SQLi — extracting data through database error messages
  • ORM Frameworks — reduce SQLi risk when used correctly, but do not eliminate it entirely

What Is SQL Injection?

SQL Injection is a vulnerability that occurs when an application builds SQL queries by concatenating strings with user data. An attacker passes a specially crafted string into a query parameter that changes the structure of the SQL command. Instead of being data, the injected string becomes part of the SQL code, allowing the attacker to execute arbitrary queries against the database. According to the Verizon Data Breach Report (2025), SQL Injection is present in 8% of all investigated data breaches.

Why Is SQL Injection Still Relevant?

Despite being a well-known vulnerability (first mentioned in the late 1990s), SQL Injection is still found in modern applications. The reason is human error: developers write code with string concatenation, legacy code is not refactored, and ORM frameworks are used incorrectly (e.g., raw queries with string interpolation). According to Veracode (2026), about 14% of all scanned applications contain at least one SQLi vulnerability.

What Can an Attacker Do?

A successful SQL Injection gives the attacker a wide range of capabilities: reading any database tables, including password hashes and personal user data; modifying and deleting records; executing administrative operations (DROP TABLE, TRUNCATE); and in some configurations, remote command execution via xp_cmdshell (MSSQL) or INTO OUTFILE (MySQL). Consequences range from user data leakage to complete loss of system control.

Types of SQL Injections

SQL injections are classified by how data is extracted from the database. The choice of method depends on how the application handles query results and error messages. The OWASP classification identifies three main types: In-band (data extracted through the same channel), Inferential/Blind (logical inferences), and Out-of-band (data transmitted through another channel).

TypeData Extraction MethodComplexityFrequency
In-band (classic)Directly through the query resultLowHigh
Blind SQLiLogical inferences from server responsesHighMedium
Out-of-bandThrough an external channel (DNS, HTTP)MediumLow

In-band SQL Injection (Classic)

The most common type. An attacker injects SQL code into a query parameter, and the result of the injection is directly visible in the server response. Two subtypes: Error-based (through DB error messages) and UNION-based (through the UNION SELECT operator). Error-based uses information from error messages, such as a MySQL syntax error that may reveal the table name or query structure. UNION-based allows combining legitimate query results with data from other database tables.

Blind SQL Injection

Used when the application does not display query results or error messages. An attacker asks yes/no questions by sending queries with logical conditions and analyzing differences in server responses (e.g., response time or page content). Time-based Blind SQLi uses delay functions (SLEEP, WAITFOR DELAY) to confirm conditions — if the page loads longer, the condition is true. This method is very slow — extracting a single record can take hours.

python
# Example of Blind SQL Injection (time-based)
# If SQLi is vulnerable, SLEEP(2) executes if condition is met
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

# If response arrives after >2 seconds — the first password letter is '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 is transmitted not via HTTP response but through alternative channels: DNS queries, HTTP requests to an external server, SMTP. Used when the application does not return query results or display errors. MySQL supports the LOAD_FILE() function, which can trigger a DNS request, and MSSQL has xp_dirtree for sending data to a remote SMB server. Out-of-band SQL Injection is effective but requires additional attacker server setup and specific DB functions.

How Does SQL Injection Work?

The SQL Injection mechanism is based on SQL using quotes for string literals. If an application inserts user input directly into an SQL query without escaping, an attacker can “close” the string and add arbitrary SQL code. For example, in the query SELECT * FROM users WHERE name = '$input', inserting ' OR '1'='1 transforms it into SELECT * FROM users WHERE name = '' OR '1'='1', which returns all users.

Classic Example: Authentication Bypass

Consider a login form with the query SELECT * FROM users WHERE username = '$user' AND password = '$pass'. If an attacker enters admin' -- in the username field and leaves the password blank, the resulting query becomes SELECT * FROM users WHERE username = 'admin' -- ' AND password = ''. The -- characters comment out the rest of the query, disabling the password check. The server returns the admin user record, and the attacker logs in without knowing the password.

python
# Example of SQL Injection — Authentication Bypass
# VULNERABLE CODE: direct string concatenation
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' --" nullifies the password check
# SAFE VERSION: parameterized query
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: Reading Other Tables

The UNION SELECT operator allows combining results from two SELECT queries. If an attacker finds a vulnerable parameter, they add UNION SELECT with a query from another table. For example: ' UNION SELECT username, password FROM admins --. The success condition is that the number of columns in both queries must match. The column count is determined through ORDER BY (inserting ' ORDER BY 1--, then 2, 3... until an error). Knowing the column count, the attacker inserts UNION SELECT with the same number of fields.

SQL Injection in Mobile Applications

Mobile applications face SQL Injection both on the server side (API) and on the client side — in local databases (SQLite, Realm). While server-side SQLi in mobile APIs is similar to web applications, local databases create an additional vector. If an application stores data in SQLite and executes queries with string concatenation, malicious data entering the local database via API can trigger SQLi during subsequent processing.

SQL Injection in SQLite on Android/iOS

The local SQLite database on a device is also vulnerable to SQL Injection if the application builds queries by concatenating strings. Content Providers on Android and Core Data on iOS use parameterization by default, but raw queries require developer attention. SQLite does not support multiple queries separated by semicolons, which limits the attacker's options but does not protect against data reading via WHERE conditions. Always use selectionArgs in Android and NSPredicate with parameters in iOS.

SQL Injection via Mobile Application API

The API that a mobile application communicates with is vulnerable just like any web server. Mobile developers often assume SQLi is only a backend issue, but the vulnerability occurs at the API endpoint that accepts parameters from the client. Separation of responsibilities does not protect: if the backend developer forgot to parameterize the query, the user's mobile app becomes an attack vector. Require the backend to use ORM or prepared statements.

kotlin
// Example of SQL Injection in Local SQLite on Android
// VULNERABLE CODE: direct concatenation
fun getUserVulnerable(db: SQLiteDatabase, userId: String): Cursor {
    return db.rawQuery(
        "SELECT * FROM users WHERE id = $userId", null
    )
}

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

SQL Injection Prevention Methods

Protection against SQL Injection is based on a simple principle: never trust user input in SQL queries. The only reliable method is query parameterization (prepared statements), where SQL code and data are passed separately. All other methods — escaping, validation, WAF — are additional security layers but do not replace parameterization. According to OWASP (2025), parameterization prevents 100% of SQL Injection attacks.

Prepared Statements (Parameterized Queries)

When using prepared statements, the SQL query is first compiled by the DB server without data, and then parameter values are passed separately. The database treats parameters as data, not as executable code. Even if an attacker passes ' OR '1'='1, the database interprets it as a string value, not as SQL code. Prepared statements are supported by all modern languages and frameworks: PDO in PHP, PreparedStatement in Java, cursor.execute in Python.

ORM Frameworks and Query Builders

Modern ORMs (Hibernate, Entity Framework, SQLAlchemy, Room) automatically use parameterization when executing queries, unless the developer switches to raw queries. However, ORMs do not fully protect: constructs like @Query(value = "SELECT * FROM users WHERE name = :name", nativeQuery = true) in JPA require passing parameters via named parameters, not concatenation. Query Builders (Knex, jOOQ) also parameterize queries by default if raw methods are not used.

String Escaping (Not Recommended as Primary Method)

Escaping special characters (mysql_real_escape_string) is an outdated method that does not protect against all types of SQL Injection. The problem: escaping depends on encoding and can be bypassed when using multi-byte encodings (e.g., GBK in Asian systems). Use escaping only in legacy code where parameterization is impossible, and always in combination with strict input type validation.

MethodEffectivenessRecommendation
Prepared Statements100%Mandatory for all queries
ORM (correct usage)99%Recommended
String Escaping70% (depends on encoding)Legacy only
Input Validation (white-list)50% (numbers only)Additional
WAF (Web Application Firewall)60%Additional

Principle of Least Privilege for the Database

The application account should have minimum necessary privileges: SELECT, INSERT, UPDATE, DELETE — only on tables that the application actually requires. Prohibit the use of DROP, TRUNCATE, CREATE for the application account. This limits damage even in case of a successful SQL Injection: the attacker will not be able to delete tables or execute administrative operations.

Tools for Detecting SQL Injections

Regular SQL Injection testing should be part of the secure development pipeline. A combination of static analysis, dynamic scanning, and manual penetration testing yields the best results. According to the Synopsys Cybersecurity Report (2025), automated scanners find up to 70% of SQLi vulnerabilities, but complex Blind attacks require manual testing.

  • sqlmap — the most popular tool for automatic detection and exploitation of SQL Injection
  • OWASP ZAP — a free DAST scanner with active SQLi scanning modules
  • Burp Suite Scanner — a professional tool with automatic SQL Injection detection
  • SonarQube — static code analysis for vulnerabilities, including SQLi patterns
  • CodeQL — semantic code analysis for finding SQL injections in source code

For mobile applications, local SQLite analysis is also important: check all rawQuery calls, ContentProvider queries, and Room queries with rawQuery. Tools: Android Studio Lint (detects SQLi in SQLite), MobSF (Mobile Security Framework) for automatic static and dynamic APK/IPA analysis. It is also recommended to test API endpoints using sqlmap with proxy interception of the mobile application's traffic.

Frequently Asked Questions

What is the difference between SQL Injection and NoSQL Injection?

SQL Injection attacks relational databases through SQL queries. NoSQL Injection targets non-relational databases (MongoDB, Couchbase) through their query operators ($gte, $ne, $where). In MongoDB, injection is possible if the application builds a BSON document from a JSON string. Protection mechanisms are similar: parameterization and type validation.

How to detect SQL Injection in code on my own?

Find all places where SQL queries are formed by string concatenation with user data. Look for patterns like "SELECT ... WHERE id = " + userId or f"UPDATE ... SET name = '{name}'". Each such line is a potential SQL injection. Replace all of them with parameterized queries or prepared statements.

Does ORM automatically protect against SQL Injection?

ORM frameworks automatically protect only if you use their Query Builder methods and named parameters. If you use raw queries (nativeQuery in JPA, rawQuery in Room), the protection does not work — you must pass parameters through prepared expressions, not through string concatenation.

What is Second-Order SQL Injection?

Second-Order SQL Injection is an attack where malicious data is stored in the database as safe, but then used in another query without escaping. For example, an attacker registers with a username like ' OR '1'='1. The data is saved as a string — there is no attack at registration. But if another query uses the username in SQL without parameterization, the injection triggers.

Can NoSQL Injection be more dangerous than SQL Injection?

NoSQL Injection can be potentially more dangerous due to lower developer awareness. Developers know about SQL Injection and most use ORMs, but few know about NoSQL Injection. In MongoDB, an improperly formed query can return all documents in a collection. Protection is the same — prepared statements (BSON parameterization) and strict input validation.

Summary

  • SQL Injection — an attack that injects SQL code through unescaped user parameters in database queries
  • Main Types — In-band (classic), Blind (time-based), Out-of-band (via external channel)
  • Query Parameterization — the only 100% reliable method of protection against SQL Injection
  • ORM Myth — ORM protects only when using built-in methods; raw queries with concatenation remain vulnerable
  • Principle of Least Privilege — restricting the DB account's privileges minimizes damage in case of a successful attack
  • Regular Testing — sqlmap, OWASP ZAP, SonarQube should be part of the CI/CD pipeline
  • Local SQLite — mobile applications must also parameterize queries to the local database

We will develop a mobile application turnkey

IT Sectr creates iOS and Android applications for startups and businesses since 2017. We will advise you and propose the best solution.

Discuss the project

Read also