flawopen.com/SQL-инъекция в Rust/sqlx
Предотвращает ли проверка sqlx при компиляции SQL-инъекции?
query! при компиляции сверяет литеральный запрос со схемой реальной базы данных; это не делает задним числом безопасным динамически собранный запрос. Передавайте значения отдельно через связанные параметры.
let user_id: String = read_user_input();
let q = format!(
"SELECT id FROM users WHERE id = '{}'",
user_id
);
// Representative only: data and SQL syntax are mixed.
// Never pass user-influenced SQL as AssertSqlSafe.
let user_id: &str = read_user_input();
// PostgreSQL; query! checks the configured schema.
sqlx::query!(
"SELECT id FROM users WHERE id = $1",
user_id
).fetch_one(&pool).await?
Что именно проверяется при компиляции
Макрос SQLx 0.9 query! требует строковый литерал и во время сборки проверяет синтаксис, типы параметров и результатов по настроенной схеме базы данных; настройте DATABASE_URL или используйте сохранённые в репозитории офлайн-метаданные. Этот пример относится к PostgreSQL: здесь используется маркер $1. SQLx рекомендует $1 для PostgreSQL и SQLite; MySQL и MariaDB используют позиционные маркеры ?. Функция времени выполнения query() может связывать значения через .bind(), если структура SQL фиксирована или контролируется приложением. В SQLx 0.9 динамическую строку нужно передавать через AssertSqlSafe; этот тип лишь утверждает, что запрос безопасен, но не очищает строку. Не используйте его, чтобы пометить безопасной строку с интерполированными недоверенными значениями.
Как проверить кодовую базу
rg -n 'format!\s*\(|sqlx::query(_as)?\s*\(' --glob '*.rs'Часто задаваемые вопросы
Используйте query!, если требования к литеральному запросу и схеме при сборке подходят проекту: макрос добавляет проверку SQL и типов при компиляции. Динамический query() тоже безопасен, если связывать каждое значение через .bind(). В любом случае не вставляйте недоверенные данные в синтаксис SQL.
Источники
- flawopen.com — SQL-инъекция в Rust
- Документация SQLx — макрос query! и маркеры баз данных
- Документация SQLx — AssertSqlSafe (утверждение, не очистка)