UNION-BASED
ABOUT
When an application is vulnerable to SQL injection, and the results of the query are returned within the application's responses, you can use the UNION keyword to retrieve data from other tables within the database. This is commonly known as a SQL injection UNION attack.
The UNION keyword enables you to execute one or more additional SELECT queries and append the results to the original query. For example:
SELECT a, b FROM table1 UNION SELECT c, d FROM table2WHERE TO LOOK
APPROACH
This SQL query returns a single result set with two columns, containing values from columns a and b in table1 and columns c and d in table2.
For a UNION query to work, two key requirements must be met:
The individual queries must return the same number of columns.
The data types in each column must be compatible between the individual queries.
To carry out a SQL injection UNION attack, make sure that your attack meets these two requirements. This normally involves finding out:
How many columns are being returned from the original query.
Which columns returned from the original query are of a suitable data type to hold the results from the injected query.
1. Determining column count
There are two effective methods to determine how many columns are being returned from the original query:
Those two methods are not gonna necessarily work, it would depend on an application (as always). If the output is present, you can move forward to use UNION to get some useful information. If the difference is in time delay, that's probably TIME-BASED Injection. If the difference is different error output, theoretically it could be ERROR-BASED Injection. If nothing of it works, it still could be BLIND Injection
2. Examining the database
When you have determined the number of columns returned by the original query and found which columns can hold string data, you are in a position to retrieve data, just for that you need to know type of database, it's version, the tables, columns and their data types.
Oracle
SELECT banner FROM v$version
SELECT version FROM v$instance
Microsoft
SELECT @@version
PostgreSQL
SELECT version()
MySQL
SELECT @@version
Most database types (except Oracle) have a set of views called the information schema. This provides information about the database.
For example, you can query information_schema.tables to list the tables in the database:
This output indicates that there are three tables, called Products, Users, and Feedback.
You can then query information_schema.columns to list the columns in individual tables:
Start small, then steadily build toward greater impact
3. Identifying reflected columns
A UNION query may execute correctly while producing no usable signal if the injected output lands in a column that the application does not render. The frontend determines which parts of the result set become observable. Reflection defines the extraction channel. This step separates syntactic success from operational visibility and prevents false confidence when the backend executes correctly but the UI suppresses output. Understanding rendering behavior also reveals truncation limits, encoding transformations, and formatting constraints.
4. Validating data type compatibility
Each reflected column imposes semantic constraints on what data can be safely injected and rendered. Numeric columns, strict type systems, implicit coercion rules, and binary representations influence whether extracted data survives intact. Misaligned types cause silent corruption, runtime errors, or invisible output. This step ensures that the extraction channel can faithfully carry the intended information without distortion or instability.
5. Structuring readable output
Even when extraction is technically possible, raw output may be inefficient, fragmented, or difficult to interpret. Consolidation of multiple values into a single visible channel improves signal density and reduces dependency on UI layout. Delimiters, ordering consistency, and aggregation strategies increase human readability and reduce ambiguity. This step optimizes information throughput under display and rendering constraints.
6. Adapting to engine-specific behavior
SQL is not uniform across implementations. Function availability, concatenation semantics, aggregation behavior, casting strictness, identifier handling, comment parsing, and mandatory query structure differ between engines. Assumptions valid in one environment may silently fail in another. This step enforces adaptability and prevents overgeneralization from isolated success cases.
7. Accounting for transport and decoding layers
Input does not travel directly from client to SQL parser. It passes through encoding, decoding, normalization, filtering, and sometimes security middleware. Each layer can transform characters, whitespace, delimiters, and escape sequences. Payload intent must survive these transformations intact. Misunderstanding this chain leads to malformed logic, inconsistent behavior, and false diagnostics. This step maintains alignment between conceptual payload design and actual executed query structure.
EXAMPLES
PREVENTION
WIP
ADDITIONAL NOTES
Use trailing space (-- ) with a space after it because it's usually required in SQL engines
Last updated


