Information Security

SQL Injection

2008. Albert Gonzalez attacks Heartland Payment Systems - the largest payment card processor in the United States. Method: SQL Injection in a web form. Result: 130 million card numbers. Sentence: 20 years in prison. SQL Injection has been in the OWASP Top 10 since 2003 - twenty years at the top. Not because it is technically sophisticated, but because string concatenation is still the default pattern taught in tutorials and found in production code.

  • **Heartland 2008**: 130 million card numbers via SQLi in a payment form - the largest financial data breach in history at the time.
  • **Twitch 2021**: SQLi in a sort field leaked 128 GB of data, including streamer payout amounts.
  • **Yahoo 2012**: SQLi exposed 450,000 credentials via the search API and were published publicly.

SQL Injection: When Input Becomes Code

SQL Injection is an attack where user input is interpreted by the database as an SQL command. The developer believes data is being passed. The database sees code. OWASP Top 10 #1 since 2003 - not by accident. The vulnerability lives in millions of production systems because the root cause is a single bad habit: concatenating user input into SQL strings.

SQLi is not limited to login forms. Any field that reaches an SQL query is a potential injection point: search boxes, URL parameters (?id=5), sort fields, HTTP headers, cookies. In 2021, an SQLi in a sort field at Twitch leaked 128 GB of data including streamer payouts.

A developer filters single quotes in the username field. Which payload bypasses this protection?

Parameterized Queries: Separating Code from Data

The root cause of SQLi is mixing data and code in the same string. Parameterized queries (prepared statements) solve this by separating them physically. The database receives two distinct objects: the SQL template and the parameters. Data values can never be interpreted as SQL syntax.

Why does parameterization succeed where filtering fails? Because the protection is in the transmission protocol, not the content. Even '; DROP TABLE users;-- arrives in the database as the string "'; DROP TABLE users;--", not as SQL commands. The database never parses parameter values as code.

Code: query = f"SELECT * FROM products WHERE category='{category}' ORDER BY {sort_field}". The category is parameterized, but sort_field comes from the URL. What happens?

ORM Pitfalls: Safe by Default, Unsafe by Exception

ORMs such as TypeORM, SQLAlchemy, and Hibernate parameterize queries automatically. This sounds like 'SQLi is impossible with an ORM.' That is wrong. Every ORM has escape hatches for complex queries - and that is exactly where vulnerabilities live.

HackerOne report #1027147 (2021): SQLi in a production Rails app via ActiveRecord .where("name = '#{params[:name]}'"). The ORM was in use, but with string interpolation. Payout: $7,500. This pattern appears in many legacy Rails codebases. Second-order SQLi is also common: data stored safely via parameterization is later used in a different query without parameterization.

A developer uses TypeORM's userRepo.find({ where: { username, role } }). Where is the potential risk?

Blind SQLi: Extracting Data Without Seeing Errors

Most vulnerable systems do not show SQL errors to users. Developers assume: 'no error message means no attack vector.' This is an illusion. Blind SQLi extracts data through indirect signals: changes in response content (boolean-based) or response timing (time-based).

sqlmap automates Blind SQLi: sqlmap -u 'http://target.com/api/user?id=1' --dump. The tool tries all injection types, identifies the database engine, and extracts data. On a vulnerable system, a full database dump takes minutes. WAFs (Cloudflare, AWS WAF) block known patterns but are bypassable via encoding and obfuscation. Parameterization is the only reliable defense.

An application returns the same HTML page for both success and error cases, always 200 OK. Is SQL Injection still possible?

Key Ideas

  • **Root cause**: mixing data and code via string concatenation. The database interprets input as SQL commands.
  • **Defense**: parameterized queries (prepared statements) at every query. ORDER BY and column names cannot be parameterized - use an allowlist.
  • **ORM is not magic**: raw() and query() methods bypass parameterization. Audit all escape hatches.
  • **Blind SQLi**: even with no error output, data can be extracted via boolean or time-based responses. sqlmap automates this in minutes.

Related Topics

SQL Injection connects to the broader web security landscape:

  • CSRF, SSRF, CORS — The next class of web attacks - request forgery rather than injection into queries.
  • XSS — XSS is JavaScript injection into HTML - the same untrusted-input pattern applied to a different interpreter.
  • Penetration Testing Tools — sqlmap is the standard tool for automating SQLi discovery and exploitation during pen tests.

Вопросы для размышления

  • A legacy codebase uses string concatenation in 200 queries. What is the safest migration strategy to parameterized queries without breaking functionality?
  • A WAF blocks all known SQLi patterns. Does this mean parameterized queries are no longer necessary?
  • How would you detect second-order SQL Injection in a code review when the injection and the vulnerable query are in different modules?

Связанные уроки

  • sec-03
  • sec-08
  • sec-09
  • sec-29
  • db-02-relational-model
SQL Injection

0

1

Sign In