SQL Injection Explained
Learn about SQL Injection attacks, how they work, and how to test for them.
SQL Injection (SQLi) is a security vulnerability where an attacker inserts malicious SQL code into an application’s input fields to manipulate the database query executed by the server.
It occurs when user input is directly concatenated into SQL statements without proper validation or parameterization.
SQL Injection has consistently been listed as a top risk by OWASP because of its high impact and ease of exploitation.
How It Works
Vulnerable code example:
SELECT * FROM users WHERE username = '$username' AND password = '$password';
If input is:
username: admin
password: ' OR '1'='1
The resulting query becomes:
SELECT * FROM users WHERE username = 'admin' AND password = '' OR '1'='1';
Since '1'='1' is always true, authentication is bypassed.
What Attackers Can Do
Depending on permissions, attackers may:
- Bypass authentication
- Read sensitive data
- Modify records
- Delete data
- Escalate privileges
- Execute administrative operations
In severe cases, they can take full control of the database server.
Common Types of SQL Injection
1. In-Band SQLi
Data is retrieved using the same communication channel.
- Error based SQLi
- Union based SQLi
2. Blind SQLi
Application does not return database errors directly.
- Boolean based
- Time based
Example time based payload:
' OR IF(1=1, SLEEP(5), 0) --
3. Out-of-Band SQLi
Data is exfiltrated using a different channel, such as DNS.
Why It Happens
- Dynamic query building
- Lack of input validation
- No parameterized queries
- Excessive database privileges
- Detailed database error messages exposed
Prevention
1. Parameterized Queries (Prepared Statements)
Never concatenate raw input into SQL.
Example:
cursor.execute("SELECT * FROM users WHERE username=%s", (username,))
2. ORM Usage
Frameworks like Django ORM, Hibernate, and others reduce risk when used properly.
3. Input Validation
Validate type, length, and format.
4. Least Privilege
Application database user should not have admin rights.
5. Disable Detailed Errors
Do not expose raw SQL errors in production.
SQL Injection Testing Checklist
Aligned with risk categories highlighted by OWASP and tailored for application level security validation.
Focus is on identifying unsafe query handling, not database penetration testing.
1. Identify Injection Surfaces
Map all database interacting entry points.
High Risk Areas
- Login forms
- Registration
- Search filters
- URL ID parameters
- Sorting and pagination
- Admin panels
- Report generation
- File import features
- GraphQL resolvers
- REST query parameters
Ask:
- Does this input influence a database query?
- Is input passed to raw SQL anywhere?
2. Authentication Bypass Testing
Test login and token endpoints.
Payloads
' OR '1'='1
' OR 1=1 --
admin' --
Validate:
- Login is not bypassed
- No unexpected user session created
- Account lockout still enforced
- No SQL errors returned
3. Error Based SQLi Detection
Inject malformed input:
'
"
' OR '
Check for:
- SQL syntax errors in response
- Database names exposed
- Stack traces
- Query fragments visible
Proper behavior:
- Generic error message
- No database information leaked
4. Union Based SQLi Testing
Test data extraction possibility.
Example:
' UNION SELECT NULL,NULL --
If response structure changes or unexpected data appears, injection risk exists.
Check:
- Column count manipulation
- Data from other tables appearing
- Debug info leakage
5. Blind SQL Injection Testing
When errors are hidden.
Boolean Based
' AND 1=1 --
' AND 1=2 --
Compare responses:
- Content differences
- Status code changes
- Behavioral differences
Time Based
' OR IF(1=1, SLEEP(5), 0) --
Observe:
- Response delay
- Timeout behavior
Response time variance indicates possible vulnerability.
6. Numeric Parameter Testing
Test ID parameters:
?id=1 OR 1=1
?id=1--
?id=1; DROP TABLE users
Verify:
- Input is validated as numeric
- Invalid input rejected
- No stack traces returned
7. Search & Filter Injection
Test:
- Sorting parameters
- Filter fields
- Date ranges
- Category filters
Example:
sort=name; DROP TABLE products
Confirm:
- Parameter whitelisting exists
- Query builder rejects unexpected input
8. Stored SQL Injection
Test persistent fields:
- Profile fields
- Comments
- Admin content
- Bulk imports
Inject SQL payload and verify:
- It does not execute later
- Admin dashboards are safe
- No background job execution triggered
9. API & GraphQL Testing
For REST and GraphQL:
- Deep nested filters
- Raw where clauses
- Custom query arguments
Check:
- Query depth limits
- Parameterized resolvers
- No direct SQL exposure
10. Input Validation Review
Validate:
- Data type enforcement
- Length limits
- Allowed character restrictions
- Proper backend validation, not only frontend
Client side validation alone is insufficient.
11. Database Privilege Validation
Confirm:
- Application DB user is not root/admin
- No DROP or ALTER privileges
- No access to system tables
- Limited schema visibility
Even if injection occurs, impact should be minimized.
12. Logging & Monitoring
Verify:
- Suspicious query patterns logged
- Repeated failed injection attempts monitored
- Alerts triggered for anomalies
- Rate limiting applied to sensitive endpoints
13. Secure Coding Verification
Check codebase for:
- String concatenated SQL
- Dynamic query building
- Usage of prepared statements
- ORM safe usage
- Parameter binding everywhere
14. Regression & Automation Strategy
Include in CI:
- Negative API tests with injection payloads
- Login bypass tests
- Error exposure checks
- Response time anomaly tests
Avoid destructive queries in shared environments.
15. Risk Prioritization
Highest risk findings:
- Authentication bypass
- Data extraction via UNION
- Blind SQLi with data inference
- Admin panel injection
- Injection in multi tenant systems
These should be treated as critical severity.