Authorization disclaimer. This walkthrough is limited to the intentionally vulnerable PortSwigger Web Security Academy lab linked below. Test only systems you own or are explicitly authorized to assess.

Overview

The UNION output reveals both the database family and its randomized user schema: two text columns and version() identify PostgreSQL; informationschema.tables reveals usersoccukb, then columns usernamegfkpyb and passwordxrdklp. PostgreSQL catalog names then provide a direct route to the credential row.

Lab objective/setup

Exercise SQL injection attack, listing the database contents on non-Oracle databases through the endpoint and input recorded in the lab note. Two text columns and version() identify PostgreSQL; information_schema.tables reveals users_occukb, then columns username_gfkpyb and password_xrdklp.

What I observed

two text columns and version() identify PostgreSQL; information_schema.tables reveals users_occukb, then columns username_gfkpyb and password_xrdklp.

Two text columns and `version()` identify PostgreSQL; `information_schema.tables` reveals `users_occukb`, then columns `username_gfkpyb` and `password_xrdklp`.
Two text columns and `version()` identify PostgreSQL; `information_schema.tables` reveals `users_occukb`, then columns `username_gfkpyb` and `password_xrdklp`.
Two text columns and version() identify PostgreSQL; information_schema.tables reveals users_occukb , then columns username_gfkpyb and password_xrdklp . The visible pane contains the resulting application response.
Two text columns and version() identify PostgreSQL; information_schema.tables reveals users_occukb , then columns username_gfkpyb and password_xrdklp . The visible pane contains the resulting application response.
Two text columns and `version()` identify PostgreSQL; `information_schema.tables` reveals `users_occukb`, then columns `username_gfkpyb` and `password_xrdklp`.
Two text columns and `version()` identify PostgreSQL; `information_schema.tables` reveals `users_occukb`, then columns `username_gfkpyb` and `password_xrdklp`.

Why it is vulnerable

Two text columns and version() identify PostgreSQL; information_schema.tables reveals users_occukb, then columns username_gfkpyb and password_xrdklp. The application passes that value into the security-sensitive operation without the context-specific validation or encoding needed to prevent this result.

Walkthrough in the authorized PortSwigger lab

Use the two printable columns to display version(), enumerate information_schema.tables, inspect the discovered users table through information_schema.columns, and finally select the randomized username and password columns.

The category UNION query reads information_schema.columns and the response reveals the randomized username and password column names for the discovered users table.
The category UNION query reads information_schema.columns and the response reveals the randomized username and password column names for the discovered users table.
A final UNION SELECT requests those randomized columns from the users table, and the product page renders the administrator username beside its synthetic password.
A final UNION SELECT requests those randomized columns from the users table, and the product page renders the administrator username beside its synthetic password.
Use the two printable columns to display `version()`, enumerate `information_schema.tables`, inspect the discovered users table through `information_schema.columns`, and finally select the randomized username and password columns.
Use the two printable columns to display `version()`, enumerate `information_schema.tables`, inspect the discovered users table through `information_schema.columns`, and finally select the randomized username and password columns.

Verification

The lab is confirmed when two text columns and version() identify PostgreSQL; information_schema.tables reveals users_occukb, then columns username_gfkpyb and password_xrdklp. The captured result and the Academy solved state provide the verification; an ordinary status code alone does not.

Impact and defensive lesson

A single injectable catalog filter can expose arbitrary tables. Use prepared statements and a least-privileged database role that cannot enumerate or read unrelated authentication data.

References