SQL injection (SQLi) is an attack where someone exploits a web app’s input fields to run unauthorized SQL queries on its database. It happens when user input isn’t properly cleaned up before being added to a SQL statement, letting attackers manipulate the query’s logic. They might aim to steal data (like usernames or passwords), change records, or bypass login screens.
Here’s a basic example:
- A login form’s backend query might look like this:
SELECT * FROM users WHERE username = 'user' AND password = 'pass';
- If the app doesn’t check input, an attacker could enter this in the password field:
' OR '1'='1
- The query then becomes:
SELECT * FROM users WHERE username = 'user' AND password = '' OR '1'='1';
- Since ‘1’=’1′ is always true, the attacker logs in without a real password.
Attackers can push it further:
- To dump data: ‘ UNION SELECT * FROM sensitive_table —
- To delete stuff: ‘; DROP TABLE users; —
How Does It Work on the Client Side?
From the client side—think of an attacker using a browser or a tool—SQL injection is about sending tricky input through the app’s front-end (like forms or URLs) to mess with the server’s database. Here’s the breakdown:
- Finding Weak Spots:
- The attacker scans the website for input areas: login fields, search bars, or even URL parameters like example.com/profile?id=123. These are spots where data gets sent to the server and might end up in a SQL query.
- Building the Attack:
- They enter something sneaky. For a login password field, maybe: ‘ OR ‘1’=’1. For a URL, maybe: example.com/profile?id=1′ OR ‘1’=’1. The idea is to change how the SQL query runs, guessing at the backend structure.
- Sending It Off:
- This input goes to the server via an HTTP request. Examples:
- A POST request from a form:
- This input goes to the server via an HTTP request. Examples:
POST /login HTTP/1.1
Host: example.com
Content-Type: application/x-www-form-urlencoded
username=admin&password=' OR '1'='1
- A GET request in a URL:
example.com/search?query=apple' UNION SELECT username,password FROM users --
- Special characters like ‘ might get URL-encoded (e.g., %27), but the effect is the same.
- Checking the Result:
- The attacker looks at what comes back. If ‘ OR ‘1’=’1 logs them in, jackpot. If a search bar spits out odd data or an error like “SQL syntax error,” they know the input hit the database raw.
- Digging Deeper:
- Using browser dev tools (F12) or something like Burp Suite, they tweak the input. Maybe ‘; DROP TABLE users; –—if the site breaks, they’ve done damage. Automated tools like SQLMap can speed this up, pulling data straight to their screen.
Client-Side Example:
You type test into a site’s search bar—normal results. Then you try test’ OR ‘1’=’1 and get an error like “syntax error near ‘1’”. That’s a clue the app’s vulnerable. Next, you might try test’ UNION SELECT username,password FROM users — and see user data pop up in the results—all from your browser.
Real-World Cases of SQL Injection Attacks
- Sony Pictures (2011)
- Hackers used SQLi to leak over 1 million accounts (emails, passwords, etc.) from Sony’s servers via a flawed web app. Huge reputational hit and legal costs followed.
- Lesson: Big names aren’t immune to simple mistakes.
- Heartland Payment Systems (2008)
- SQLi on a payment app exposed 130 million credit card numbers over months, costing over $140 million. Attackers slipped in via unfiltered input.
- Lesson: Undetected SQLi can bleed data for ages.
- TalkTalk (2015)
- A teen exploited SQLi on TalkTalk’s site, leaking 157,000 customers’ data (including bank info). Fined £400,000, it showed how easy SQLi can be.
- Lesson: Basic attacks still work if defenses are weak.
How to Defend Against SQL Injection
Here’s how to lock it down:
- Prepared Statements/Parameterized Queries
- Best defense. Use placeholders instead of raw input. Python example:
query = "SELECT * FROM users WHERE username = ? AND password = ?"
cursor.execute(query, (username, password))
- Keeps input as data, not code. Works in Java (PreparedStatement), PHP (PDO), etc.
- Input Validation
- Check input fits expected patterns. Python regex example:
import re
if not re.match("^[a-zA-Z0-9]+$", username):
raise ValueError("Invalid username")
- Enough? Nope. It catches obvious garbage, but sneaky input like ‘ OR ‘1’=’1 can slip through.
- Escaping Inputs
- If stuck without prepared statements, escape characters (e.g., ‘ to \’). Use stuff like mysql_real_escape_string(), but it’s riskier than parameterization.
- ORMs
- Tools like SQLAlchemy or Hibernate handle queries safely—if set up right.
- Least Privilege
- Limit database rights. Example:
GRANT SELECT ON users TO 'app_user'@'localhost';
- Won’t stop SQLi but caps the damage.
- Web Application Firewall (WAF)
- Blocks fishy patterns like UNION SELECT. Good backup, not perfect—attackers can dodge it.
- Security Audits
- Test with tools like SQLMap to find holes before attackers do.
Is Input Validation Enough?
Not really. It’s a start—stops some junk input—but doesn’t fix the core problem of input running as code. If you allow letters and numbers, ‘ UNION SELECT still fits. Prepared statements are the real deal; validation’s just extra armor.
Final Thoughts
SQLi is a client-side guessing game that exploits server-side sloppiness. Attackers poke at forms and URLs; you stop them with prepared statements and smart design. For WordPress, if you’re pasting this, use the “Code” block or “Text” mode in the classic editor to keep formatting intact.