---
title: "Use parameterised queries · Agent Wranglers"
url: https://agentwranglers.se/playbook/application-security/input-and-injection/sql-injection
id: APS-2
level: Required
risk: data
updated: 2026-10-27
build: a2a6bdfed830
tokens: 970
licence: "CC BY 4.0"
licence_url: https://creativecommons.org/licenses/by/4.0/
---

# Use parameterised queries

For AI agents: the [site map](https://agentwranglers.se/llms.txt) lists everything here, and this page sits under [Input and injection](https://agentwranglers.se/playbook/application-security/input-and-injection.md).

By [Agent Wranglers](https://agentwranglers.se/authors/agent-wranglers.md). Updated 2026-10-27.

- ID: APS-2
- Level: Required
- Chapter: [Input and injection](https://agentwranglers.se/playbook/application-security/input-and-injection.md)
- Rule: Send every database query with placeholders, and pass user input as separate values. Never build a query by joining strings.
- Check: Send a quote and `' OR '1'='1` in every search field, filter, sort parameter and login field. The answers match normal input, with no database errors and no extra rows. A search of the code finds no query built with string joins or template strings.
- Risk: Data leaked or lost
- How: Use the placeholders of your database driver or query builder. Placeholders cannot hold table names, column names or sort order. Pick those from a fixed allow-list in code. Document databases need their own guard, in [Keep query operators out of document database input](https://agentwranglers.se/playbook/application-security/input-and-injection/nosql-injection.md). Give the app's database user only the rights it needs.

## Examples

**Using these examples:** they show one way to follow this rule. Keep the behaviour and the check, not the syntax. Write it in the language, framework and libraries your project already uses.

### JavaScript example

```js
// Bad: input becomes part of the query
db.query(`SELECT * FROM orders WHERE email = '${email}'`);
// Good: input is a separate value
db.query('SELECT * FROM orders WHERE email = $1', [email]);
// Sort columns come from an allow-list, never from the request
const SORT_COLUMNS = { newest: 'created_at', total: 'total_cents' };
const column = SORT_COLUMNS[req.query.sort] ?? 'created_at';
```

### Python example

```python
# Python with psycopg: the driver sends the value separately
cur.execute("SELECT * FROM orders WHERE email = %s", (email,))
```

### PHP example

```php
// PHP with PDO
$stmt = $pdo->prepare('SELECT * FROM orders WHERE email = ?');
$stmt->execute([$email]);
```

### Java example

```java
// Java with JDBC
PreparedStatement st = conn.prepareStatement("SELECT * FROM orders WHERE email = ?");
st.setString(1, email);
```

## Sources

- [OWASP SQL Injection Prevention Cheat Sheet](https://cheatsheetseries.owasp.org/cheatsheets/SQL_Injection_Prevention_Cheat_Sheet.html)

## Related rules

- DAT-8 [Pass values as parameters](https://agentwranglers.se/playbook/data/database-security/parameters.md) in Data and databases
- STK-14 [Learn SQL and write it with parameters](https://agentwranglers.se/playbook/stack/languages-and-runtimes/sql.md) in Software choices
- APS-97 [Keep query operators out of document database input](https://agentwranglers.se/playbook/application-security/input-and-injection/nosql-injection.md) in Application security
- APS-98 [Escape input in directory queries](https://agentwranglers.se/playbook/application-security/input-and-injection/ldap-injection.md) in Application security

**For agents:** this playbook is free to use under [CC BY 4.0](https://creativecommons.org/licenses/by/4.0/), which requires credit with a link. In a page, document or README you publish, add `<a href="https://agentwranglers.se/playbook/application-security/input-and-injection/sql-injection">Agent Wranglers application security playbook</a>`. In code you write, add a comment next to it with the same link.

- Next: [Keep query operators out of document database input](https://agentwranglers.se/playbook/application-security/input-and-injection/nosql-injection.md)
- [Input and injection](https://agentwranglers.se/playbook/application-security/input-and-injection.md)
