freeCodeCamp/guide/russian/security/query-parameterization/index.md

77 lines
4.3 KiB
Markdown
Raw Normal View History

2018-10-12 20:00:59 +00:00
---
title: Query Parameterization
localeTitle: Параметрирование запроса
---
## Параметрирование запроса
Обычная ошибка при подключении вашей программы к базе данных - это принять вход пользователя и применить его непосредственно к базе данных, не проверив его в первую очередь. Это опасная привычка, и вы можете услышать, что более опытные разработчики предупреждают других о том, что они «дезинфицируют ввод» или «параметризовать запросы».
Начнем с краткого примера, демонстрирующего проблему:
_(следующие фрагменты написаны на C # для MySQL, но концепция применима к любому языку и базе данных)_
### Проблема
```csharp
public void RetrieveEmployeeInfo(string username)
{
using (var connection = new MySqlConnection("valid_connection_string"))
{
var query = "SELECT * FROM EMPLOYEES WHERE USERNAME = '" + username + "'";
using (var command = new MySqlCommand(query, connection))
{
var reader = command.ExecuteReader();
while (reader.Read())
{
// do something with the results of your query, like display the employee
}
}
}
}
```
На первый взгляд это может показаться довольно безобидным. Если пользователь вводит «JDOE» в вашу программу и передается этой функции, вы в конечном итоге выполняете такой запрос:
```sql
SELECT * FROM EMPLOYEES WHERE USERNAME = 'JDOE';
```
Проблема становится более очевидной, если вы считаете, что происходит, если пользователь е_ вводит то, что вы ожидаете. Что делать, если они набирают что-то вроде `JDOE'; DROP TABLE EMPLOYEES; --` ? Теперь ваша строка запроса будет выглядеть так, что выберет информацию о сотруднике, а затем удалит всю таблицу РАБОТНИКОВ!
```sql
SELECT * FROM EMPLOYEES WHERE USERNAME = 'JDOE'; DROP TABLE EMPLOYEES; --'
```
### Решение
Чтобы предотвратить такие проблемы, мы можем параметризовать наши запросы. Давайте посмотрим на другой пример:
```csharp
public void RetrieveEmployeeInfo(string username)
{
using (var connection = new MySqlConnection("valid_connection_string"))
{
var query = "SELECT * FROM EMPLOYEES WHERE USERNAME = @username";
using (var command = new MySqlCommand(query, connection))
{
command.Parameters.AddWithValue("username", username);
var reader = command.ExecuteReader();
while (reader.Read())
{
// do something with the results of your query, like display the employee
}
}
}
}
```
Теперь, что произойдет, если пользователь вводит в `JDOE'; DROP TABLE EMPLOYEES; --` ? Наша программа заканчивает выполнение запроса, подобного этому, и, не найдя сотрудника, чье имя пользователя действительно соответствует этому вводу, просто не возвращает записей.
```sql
SELECT * FROM EMPLOYEES WHERE USERNAME = 'JDOE\'; DROP TABLE EMPLOYEES; --'
```
Независимо от того, какой язык или база данных вы используете, если вы рассматриваете запрос базы данных с использованием пользовательского ввода, проверьте документацию для правильного способа параметризации запросов.