Many do, usually by accident. A sample that joins a user value into a SQL string is short and readable, so it gets copied. Rewrite database examples to use parameterized queries, and add a one-line note explaining why. The OWASP cheat sheet names parameterized queries as the way to prevent SQL injection.
Why docs authors reach for string building
String building has an appeal in a tutorial. The query is visible in one line, the output is easy to explain, and there is no extra concept to introduce. The cost lands later. The OWASP Query Parameterization Cheat Sheet says SQL injection is best prevented through parameterized queries, and it provides code samples for the common web languages to show how.
A reader who learned from your page will not stop to question the pattern. They will reproduce it in their own project, with user input in place of your hardcoded value.
What the unsafe and safe samples look like
# Unsafe: user input becomes part of the SQL text
cursor.execute("SELECT * FROM users WHERE email = '" + email + "'")
# Safer: the value travels separately from the SQL text
cursor.execute("SELECT * FROM users WHERE email = %s", (email,))
The placeholder marker differs by database driver, so check the documentation for the driver your tutorial uses. The principle stays the same: the query structure and the data are sent separately.
Audit steps for a docs repository
- Search code blocks for the SQL keywords SELECT, INSERT, UPDATE and DELETE next to string joins, f-strings, template literals or format calls.
- For every hit, ask whether any part of the string could come from a user, a URL or a file. If yes, rewrite it.
- Where the sample uses a hardcoded value, still prefer the parameterized form so the pattern is the one readers copy.
- Add a short callout the first time a query appears: "Values go in as parameters, never joined into the text."
- For parts parameters cannot cover, such as table names or sort order, show an allow list of known values. Do not tell readers to escape strings by hand.
- Add the search to your docs build as a warning, so new samples are checked.
Common objections
| Objection | Response |
|---|---|
| It makes the sample longer | By one argument. The cost of the longer line is small. |
| Our sample has no user input | Readers will add it. Teach the pattern you want repeated. |
| We use an ORM | Many ORMs have raw query escape hatches. Show the safe form of those as well. |
| It is only a demo | Demos are copied more than production code is read. |
Test the samples you ship
Do not assume the tutorial is safe because it looks right. Run the sample against a test database with a value containing a single quote, and confirm it behaves as plain data. A quote in the input should not change the shape of the query.
For deeper guidance see sql injection lab: fix with parameterized queries and what to look for in sql code during pull request review.
Try it yourself
Static analysis can point at risky string built queries in a repository.
Click through it at your own pace, or open it full screen.
Safeguard's code scanning can run against the sample repositories your docs publish, and policy gates can hold a pull request until findings are reviewed. The free scan is at https://gold.safeguard.sh/scan.
Quick check
Is escaping quotes by hand a fair alternative in a tutorial?
No. Parameterized queries are the recommended defence, and hand escaping is easy to get wrong. Teach the parameter form.
What about a hardcoded value in an example?
Use the parameterized form anyway. Readers copy the pattern, not your constant.
Sources
Last reviewed: 19 October 2026.