

0 / 2 embers
0 / 3000 xp
click for more info
Complete a lesson to start your streak
click for more info
Still calibrating
click for more info
Not enough gems
Cost: 6 gems
1: Injection
incomplete
2: Fixing SQL Injection
incomplete
3: Injection Beyond SQL
incomplete
4: Safe Validation and Sanitization
incomplete
5: When to Sanitize
incomplete
6: Unsafe Archive Extraction
incomplete
7: Safe Archive Extraction
incomplete
8: LLM Prompt Injection
incomplete
9: Limiting Tool Calls
incomplete
10: Narrow Tool Interfaces
incomplete
11: File Upload Security
incomplete
Back
ctrl+,
Next
ctrl+.
This lesson's interactive features are locked, please to keep using them
The best defense against SQL injection is to parameterize every untrusted value. A parameterized query sends SQL text and values to the database separately:
rows, err := database.QueryContext(
ctx,
"SELECT id, name FROM products WHERE name LIKE ? LIMIT ?",
"%"+query+"%",
maxResults,
)
The database parses the statement's structure before binding query and maxResults as data. Quotes and comment markers inside those values cannot become SQL syntax.
Query generators such as sqlc preserve that boundary while adding compile-time types. Bearly Secure already has a generated SearchActiveProducts query, so application code can call it without constructing SQL at runtime.
Bearly Secure builds its product-search SQL with string concatenation. Replace the dynamic statement with the existing parameterized sqlc query.
go run ./cmd/seed
go run ./cmd/server
With Bearly Secure still running, run and submit the CLI tests from the project root.