# SQL built from values with f-strings, concatenation or template strings

*Shortcuts that trade away safety*: one of the ways AI coding agents bloat software, from lessloc's [pattern catalog](https://lessloc.org/patterns/index.md). lessloc catches it as [`unsafe`](https://lessloc.org/guide/reference.md#tier-1): pass values as query parameters.

## What makes SQL built from values instead of query parameters a bad practice?

The standards that call it a bad practice: [CWE-89](https://cwe.mitre.org/data/definitions/89.html) SQL Injection; OWASP Top 10 A03:2021 Injection.

## What does lessloc do about SQL built from values instead of query parameters?

lessloc catches it as [`unsafe`](https://lessloc.org/guide/reference.md#tier-1): pass values as query parameters.

- `unsafe` (tier 1): A shortcut that trades away safety: SQL built from values, HTML built or escaped by hand, `Math.random()` for secrets, a fast hash for passwords, certificate checks turned off, text run as code.

## Examples

Caught as `unsafe`:

```python [cj.py]
def find(db, name):
    return db.execute(f"SELECT * FROM users WHERE name = '{name}'")
```

Written well:

```python [cj.py]
def find(db, name):
    return db.execute("SELECT * FROM users WHERE name = ?", (name,))
```

## Related patterns

Hand-written versions of what the platform does safely. They are short, which is why agents reach for them. The other patterns in [Shortcuts that trade away safety](https://lessloc.org/patterns/index.md#shortcuts-that-trade-away-safety):

- [HTML built or escaped by hand](https://lessloc.org/patterns/html-by-hand.md): lessloc catches it as `unsafe`: use `textContent` or the framework's rendering.
- [Math.random() or random for tokens and passwords](https://lessloc.org/patterns/weak-randomness.md): lessloc catches it as `unsafe`: `crypto.randomUUID()`, `getRandomValues()` or the `secrets` module.
- [Fast hashes (MD5, SHA-1, SHA-256) for passwords](https://lessloc.org/patterns/password-hash.md): lessloc catches it as `unsafe`: bcrypt, scrypt or argon2.
- [Certificate checks turned off](https://lessloc.org/patterns/tls-off.md): lessloc catches it as `unsafe`.
- [Running text as code: eval, exec, new Function](https://lessloc.org/patterns/eval.md): lessloc catches it as `unsafe`: parse the input instead.
