Кейс на Python с SQL-инъекцией: query = f"SELECT * FROM users WHERE name = '{name}'" — найдите уязвимость, объясните, как её эксплуатируют, и предложите корректное безопасное решение
Ваша строка `query = f"SELECT * FROM users WHERE name = '{name}'"` уязвима к SQL‑инъекции: значение переменной `name` подставляется в SQL без экранирования/параметризации. Почему это опасно (как эксплуатируют) - Если злоумышленник подаст `name = "' OR '1'='1' -- "`, запрос превратится в `SELECT * FROM users WHERE name = '' OR '1'='1' -- '` — условие всегда истинно, вернутся все строки (утечка данных). - Можно выполнить вредоносные команды, напр. `name = "'; DROP TABLE users; --"` — удаление таблицы. - Риски: утечка личных данных, модификация/удаление данных, обход аутентификации и пр. Правильное безопасное решение — параметризованные (подготовленные) запросы, не конкатенировать/не форматировать SQL вручную. Примеры безопасной реализации в Python: 1) sqlite3 (placeholder `?`): ``` cur.execute("SELECT * FROM users WHERE name = ?", (name,)) rows = cur.fetchall() ``` 2) psycopg2 (Postgres, placeholder `%s`): ``` cur.execute("SELECT * FROM users WHERE name = %s", (name,)) rows = cur.fetchall() ``` 3) sqlite3 именованный параметр: ``` cur.execute("SELECT * FROM users WHERE name = :name", {"name": name}) ``` 4) SQLAlchemy ORM: ``` session.query(User).filter(User.name == name).all() ``` Дополнительно (рекомендации) - Никогда не доверяйте пользовательскому вводу; используйте параметризацию во всех запросах. - Ограничьте привилегии БД для приложения (минимум прав). - Валидация/ограничение формата входа (например, допустимые символы, длина) как доп. защита, но не вместо параметризации. - Для динамических списков используйте динамические плейсхолдеры (без прямой конкатенации значений), например: ``` placeholders = ",".join("?" for _ in names) cur.execute(f"SELECT * FROM users WHERE name IN ({placeholders})", names) ``` Коротко: устраните уязвимость, заменив f‑строку параметризованным запросом.
`query = f"SELECT * FROM users WHERE name = '{name}'"`
уязвима к SQL‑инъекции: значение переменной `name` подставляется в SQL без экранирования/параметризации.
Почему это опасно (как эксплуатируют)
- Если злоумышленник подаст `name = "' OR '1'='1' -- "`, запрос превратится в
`SELECT * FROM users WHERE name = '' OR '1'='1' -- '`
— условие всегда истинно, вернутся все строки (утечка данных).
- Можно выполнить вредоносные команды, напр. `name = "'; DROP TABLE users; --"` — удаление таблицы.
- Риски: утечка личных данных, модификация/удаление данных, обход аутентификации и пр.
Правильное безопасное решение — параметризованные (подготовленные) запросы, не конкатенировать/не форматировать SQL вручную.
Примеры безопасной реализации в Python:
1) sqlite3 (placeholder `?`):
```
cur.execute("SELECT * FROM users WHERE name = ?", (name,))
rows = cur.fetchall()
```
2) psycopg2 (Postgres, placeholder `%s`):
```
cur.execute("SELECT * FROM users WHERE name = %s", (name,))
rows = cur.fetchall()
```
3) sqlite3 именованный параметр:
```
cur.execute("SELECT * FROM users WHERE name = :name", {"name": name})
```
4) SQLAlchemy ORM:
```
session.query(User).filter(User.name == name).all()
```
Дополнительно (рекомендации)
- Никогда не доверяйте пользовательскому вводу; используйте параметризацию во всех запросах.
- Ограничьте привилегии БД для приложения (минимум прав).
- Валидация/ограничение формата входа (например, допустимые символы, длина) как доп. защита, но не вместо параметризации.
- Для динамических списков используйте динамические плейсхолдеры (без прямой конкатенации значений), например:
```
placeholders = ",".join("?" for _ in names)
cur.execute(f"SELECT * FROM users WHERE name IN ({placeholders})", names)
```
Коротко: устраните уязвимость, заменив f‑строку параметризованным запросом.