Injection

A catalog search API pastes the search term into its SQL, so an ordinary buyer turns one search box into a read of the whole database and a UNION dump of the users table. Confirm the injection, then ship a parameterized query that treats input as data.

What Is Injection?

Injection (OWASP API8:2019) is the failure that occurs when untrusted input is concatenated into a query, command, or template that an interpreter then parses, so the input can stop being a value and become part of the instruction. SQL injection is the classic shape: an endpoint builds a database query by pasting a request parameter directly into the SQL text, and a crafted parameter rewrites the query. It is distinct from broken authorization failures, where the token is honest but the server skips a permission check; here the input itself becomes code. This exercise puts you on both sides. As Bob, an ordinary self-serve buyer on Wexlar's wholesale marketplace, you probe the catalog search endpoint GET /v1/products?q=, append a single quote to trigger a raw SQL error that echoes the query, send ' OR '1'='1' -- to strip the published filter and read every row including unpublished and internal listings, and finally send a UNION SELECT that reaches the users table and returns account emails, bcrypt password hashes, and roles. As Alice, on the receiving end of a monitoring alert, you open the search handler, see the search term concatenated straight into the SQL text, and ship the durable fix: a parameterized query with a bound parameter, so the database compiles the query first and treats the term as data only. Replaying the same UNION payload against the patched build returns zero rows and no error. The exercise closes with quiz questions on why the input became code and why parameterization is the fix rather than hand-written escaping or character blocklists, and its takeaways cover why leaking a raw SQL error to a client is a gift to an attacker.

What You'll Learn in Injection

Injection — Training Steps

  1. An ordinary buyer seat

    Wexlar runs a wholesale marketplace, and it hands out self-serve buyer accounts to anyone who signs up. Bob took one, with a throwaway identity. His seat is a plain buyer: browse the catalog, place orders, nothing privileged. He opens the developer console to see what the account is and what the API offers.

  2. One search box

    Nothing in Bob's account is privileged, so there are no admin functions to reach. The one input that interests him is the catalog search: it takes whatever he types and runs a name match against the products database.

  3. A normal search

    Bob starts with an ordinary search to see the endpoint working and learn its shape. The search takes a q query parameter and returns the products whose name matches.

  4. Working as intended

    The search behaves exactly as expected. Three published laptops, only the fields a buyer should see.

  5. Append a single quote

    The oldest injection probe there is: Bob appends a single quote to his search term. If the term is being searched for as a value, a search for a name with a quote in it simply returns nothing. If it is being concatenated into SQL, the stray quote will break the query.

  6. The query, broken open

    One extra character crashed the endpoint, and the error handed Bob the confirmation he wanted.

  7. Rewrite the filter

    Now that Bob knows the term becomes part of the query, he stops breaking it and starts steering it. He crafts a term that closes the string, adds a condition that is always true, and comments out the rest of the original query.

  8. The whole table

    The filter that limited the search to published products is gone, and the response proves it.

  9. Reach another table

    Reading every product is bad; reading tables the search was never meant to touch is worse. Bob uses a UNION to append rows from a different table onto the results, selecting the same number of columns the product query returns.

  10. The credential store, in a search result

    The rows that came back are not products at all.