Перейти к содержанию

Предотвращение атак с использованием внедрения SQL-кода (SQL injection) с помощью EF Core и параметризации

Атаки путём внедрения SQL-кода (SQL injections) — одна из самых серьезных угроз для приложения.
Пусть в приложении с рецептами есть форма поиска рецепта по названию. Если мы будем собирать SQL-запрос для такого поиска вручную, то откроем путь для подобной уязвимости.

public IList<User> FindRecipe(string search)
{
    return _context.Recipes
        .FromSqlRaw("SELECT * FROM Recipes WHERE Name = '" + search + "'")
        .ToList();
}

Здесь пользовательский ввод search непосредственно включается в SQL-запрос. Создавая вредоносный ввод, злоумышленник может потенциально выполнять любые операции над БД. Например, запрос в поиске
'; DROP TABLE Recipes; --

приведёт к посторению запроса
SELECT * FROM Recipes WHERE Name = ''; DROP TABLE Recipes; --'

Выполнение такого запроса приведёт, как уже понятно, к удалению всей таблицы рецептов.
Даже если правильно настроить полномочия для БД, злоумышленники, вероятно, смогут прочитать все данные из базы.
Самый простой способ избежать этого — не создавать SQL-запросы вручную через конкатенацию строк. Даже если необходимо написать SQL-запрос вручную, можно использовать параметризацию запросов, например:
public IList<User> FindRecipe(string search)
{
    return _context.Recipes
        .FromSqlRaw("SELECT * FROM Recipes WHERE Name = '{0}'", search)
        .ToList();
}

Параметризованные запросы неуязвимы для атак с SQL injection. Если же используется EF Core (или другие ORM-инструменты) и её стандартные LINQ-запросы — в этом случае тоже всё хорошо. EF Core автоматически создаст параметризованные запросы.

Примечание

Мы говорим о атаке SQL injection, но NoSQL и документоориентированные БД также могут быть подвержены аналогичным атакам. Никогда нельзя создавать запросы, просто конкатенируя строки.


Последнее обновление : 8 мая 2023 г.
Дата создания : 24 октября 2022 г.

Комментарии

Комментарии