Безопасность C# приложений: топ-10 уязвимостей для начинающих
Безопасность программного обеспечения — одна из ключевых задач разработчика. Даже небольшое приложение на C# может стать мишенью для злоумышленников, если не учитывать распространённые уязвимости. В этой статье мы разберём 10 самых опасных уязвимостей C# (.NET), с которыми сталкиваются начинающие разработчики. Вы узнаете, как они возникают, как их эксплуатируют и, главное, как от них защититься.
1. SQL-инъекции (SQL Injection)
Это одна из старейших и самых опасных уязвимостей. Она возникает, когда пользовательский ввод напрямую конкатенируется в SQL-запрос.
Пример уязвимого кода:
string userName = Request.QueryString["user"];
string query = "SELECT * FROM Users WHERE Name = '" + userName + "'";
SqlCommand cmd = new SqlCommand(query, connection);
Как атакуют: Злоумышленник может передать в параметр user значение ' OR 1=1 --, что вернёт все записи из таблицы.
Защита: Используйте параметризованные запросы.
string query = "SELECT * FROM Users WHERE Name = @userName";
SqlCommand cmd = new SqlCommand(query, connection);
cmd.Parameters.AddWithValue("@userName", userName);
2. Межсайтовый скриптинг (XSS)
Уязвимость XSS позволяет внедрить вредоносный JavaScript-код на страницу, которая отображается другим пользователям.
Пример уязвимого кода (ASP.NET WebForms):
string comment = Request.Form["comment"];
Response.Write("<div>" + comment + "</div>");
Защита: Всегда кодируйте вывод. Используйте HttpUtility.HtmlEncode() или Razor-синтаксис (@), который автоматически кодирует данные.
Response.Write("<div>" + HttpUtility.HtmlEncode(comment) + "</div>");
3. Небезопасная десериализация
При десериализации данных из ненадёжного источника (например, из запроса или файла) злоумышленник может выполнить произвольный код на сервере.
Пример уязвимого кода (BinaryFormatter):
BinaryFormatter formatter = new BinaryFormatter();
using (var stream = new MemoryStream(data))
{
var obj = formatter.Deserialize(stream); // ОПАСНО!
}
Защита: Используйте современные сериализаторы (JSON, XML с ограничениями), проверяйте типы и никогда не десериализуйте данные от недоверенных клиентов. Избегайте BinaryFormatter, SoapFormatter и LosFormatter.
4. Недостатки аутентификации и управления сессиями
Сюда входят слабые пароли, отсутствие ограничения на количество попыток входа, незащищённые cookie сессий.
Пример уязвимости: Cookie сессии без флагов HttpOnly и Secure.
Защита:
- Используйте
IdentityилиASP.NET Core Identity. - Настройте cookie:
HttpOnly,Secure,SameSite=Strict. - Включите ограничение на число попыток входа (Account Lockout).
- Используйте HTTPS.
services.ConfigureApplicationCookie(options =>
{
options.Cookie.HttpOnly = true;
options.Cookie.SecurePolicy = CookieSecurePolicy.Always;
options.Cookie.SameSite = SameSiteMode.Strict;
});
5. Подделка межсайтовых запросов (CSRF)
Атака, при которой злоумышленник заставляет авторизованного пользователя выполнить нежелательное действие на сайте (например, перевести деньги).
Защита: Используйте антифоржные токены (Anti-Forgery Tokens). В ASP.NET Core это делается автоматически при использовании тега <form> с asp-antiforgery.
// В Razor View
<form method="post" asp-action="Delete">
@Html.AntiForgeryToken()
<button type="submit">Удалить</button>
</form>
6. Неправильная обработка ошибок и раскрытие информации
Отображение полных стектрейсов или деталей SQL-запроса в production-среде даёт злоумышленнику информацию о структуре приложения.
Защита:
- Используйте глобальный обработчик ошибок (middleware).
- В production отключайте детальные ошибки:
app.UseExceptionHandler("/Home/Error"); - Не выводите в ответе внутренние ID, версии библиотек, пути к файлам.
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
app.UseHsts();
}
7. Небезопасное хранение конфиденциальных данных
Хранение паролей, строк подключения или ключей API в открытом виде в коде или в файлах конфигурации.
Пример ошибки:
string connectionString = "Server=myServer;Database=myDB;User=sa;Password=12345"; // ОПАСНО!
Защита:
- Используйте
Secret Managerдля разработки. - Для production — Azure Key Vault, HashiCorp Vault или переменные окружения.
- Храните пароли в виде хеша (bcrypt, Argon2).
8. Недостатки контроля доступа
Пользователь может получить доступ к данным или функциям, которые ему не разрешены (например, изменить чужой пост, изменив ID в URL).
Защита: Проверяйте права доступа на серверной стороне для каждого действия. Не полагайтесь только на скрытие кнопок на клиенте.
public IActionResult Edit(int