CONSTRUCT · BIND · EXECUTE

SQL injection: actual query results

Four fictional records. Two ways to construct a query. Inspect what SQLite really returns.

Concatenated SQL

Parameterized SQL

Exact comparison evidence

Execute a query instead of guessing its outcome

The database contains four fictional records: alpha has alice, bob and O'Reilly; beta has another alice. Each comparison starts with a fresh in-memory SQLite database and closes it afterward. The left query concatenates the name into SQL text. The right query prepares a fixed statement and binds tenant and name separately. Returned rows and errors come from the SQLite engine, not a keyword detector. No server, account, customer database or production credential is contacted.

Choose an input and inspect both paths

Name input is editable text with a maximum length of two hundred fifty-six characters. Run comparison executes the current text; typing alone does not repeatedly execute queries. Example fills the input and runs an ordinary name, an apostrophe, a true or false injected predicate, an unknown name, a syntax error or literal markup. Requested tenant selects alpha or beta and reruns the comparison. Restore defaults returns to alpha and alice. Stop execution terminates a running worker; a five-second limit also stops slow queries automatically. Each subsequent run creates a new isolated worker and database.

See an ordinary apostrophe break concatenation

Select Apostrophe name. The stored alpha record named O'Reilly exists, but direct string concatenation creates malformed SQL because the apostrophe changes its syntax. The left panel shows SQLite's actual error. The bound query returns record three because the whole string remains a data value. This example is not an attack classification: normal human names can expose the same unsafe construction. Select Unknown name and both queries return zero rows without an error, which is different from a failed query.

Observe a predicate changing the tenant boundary

Select True predicate. The inserted quote ends the string, OR adds an always-true alternative, and the comment consumes the trailing quote. The concatenated query returns all four rows, including beta's alice, even with requested tenant alpha. The parameterized query finds no name equal to that complete input and returns zero rows. Select False predicate to see that suspicious-looking input does not necessarily return everything: the altered expression instead returns no rows. Inspect the actual query and row identities instead of assuming every injection-shaped string has the same effect.

Read the parameter boundary precisely

The right panel displays fixed SQL with two placeholders and a separate list of bound values. Binding protects these value positions from becoming SQL structure; it is not a way to parameterize arbitrary table names, sort directions or complete clauses. This fixture also includes an explicit tenant predicate. Parameterization alone does not invent authorization rules, restrict database privileges, validate business inputs or safely render HTML. The result tables use text nodes, so the literal markup example is displayed as text rather than inserted as page markup.

Understand execution and resource limits

The library prepares and executes only the first statement; stacked statements after a semicolon are not an implemented attack path here. Database setup is followed by SQLite query-only mode, and each comparison discards its database. The worker has no production database connection. Results are capped at one hundred displayed rows and long-running work is terminated after five seconds. These are teaching safeguards, not a claim that real services have the same limits. SQLite syntax and typing differ from other database engines. There is no login password check, network delay, query planner animation or durable data modification.

Use direct interaction for this experiment

A fixed sixty-second animation would not change the query result. This lab is intentionally a direct comparison tool: alter one input, run, inspect exact SQL, errors and returned records, then compare again. Switch the ordinary alice example from alpha to beta and verify that the bound result changes from record one to record four. Exact evidence contains the complete comparison for reproducibility. Do not paste real secrets or personal records into demonstrations; these examples require only fictional inputs.

Engine: sql.js SQLite API, version 1.13.0, served locally with its license.

Views are my own and do not represent any employer, past or present.

Search