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

77 lines
4.3 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

---
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; --'
```
Независимо от того, какой язык или база данных вы используете, если вы рассматриваете запрос базы данных с использованием пользовательского ввода, проверьте документацию для правильного способа параметризации запросов.