TGViewer
.NET Разработчик .NET Разработчик @netdeveloperdiary · 6.74K subscribers
Post #3315 1.5K
День 2770. #BestPractices
Лучшие Практики Безопасности REST API в
ASP.NET Core. Начало
Неважно, насколько чиста ваша архитектура или насколько быстро выполняются запросы — если злоумышленник может прочитать заказы другого пользователя или подделать токен, всё это не имеет значения. Большинство проблем с безопасностью API возникают из-за игнорирования основ:
- устаревший NuGet-пакет с уязвимостью,
- отсутствие валидации,
- слабая настройка аутентификации,
- слишком либеральная политика CORS,
- секрет, внесённый в систему контроля версий.
Хорошая новость в том, что ASP.NET Core из коробки предоставляет почти всё необходимое для устранения проблем.

1. HTTPS везде
Каждый запрос к API должен передаваться по зашифрованному соединению. Без HTTPS токены, пароли и личные данные передаются в открытом виде, и любой, кто находится на пути следования по сети, может их прочитать. Обычный HTTP также открывает двери для атак с понижением уровня безопасности, когда злоумышленник заставляет клиента использовать небезопасное соединение. ASP.NET Core предоставляет два инструмента. UseHttpsRedirection перенаправляет HTTP-запросы на HTTPS, а HSTS (HTTP Strict Transport Security) указывает браузерам подключаться только по HTTPS. Совместимые браузеры вообще отказываются взаимодействовать с вашим API по HTTP, что блокирует атаки с понижением уровня безопасности:
var builder = WebApplication.CreateBuilder(args);

builder.Services.AddHsts(opts =>
{
opts.MaxAge = TimeSpan.FromDays(365);
opts.IncludeSubDomains = true;
opts.Preload = true;
});

var app = builder.Build();

if (!app.Environment.IsDevelopment())
app.UseHsts();

app.UseHttpsRedirection();
// …

HSTS пропускается в среде разработки, поскольку там часто используется http://localhost.

2. Аутентификация с помощью токенов, а не сессий
Предпочтительнее использовать аутентификацию с помощью токенов без сохранения состояния, чем серверные сессии. Сессия хранит состояние аутентификации в памяти сервера или в общем хранилище, что привязывает каждого пользователя к серверу и затрудняет горизонтальное масштабирование. Токен содержит подтверждение личности, поэтому любой экземпляр вашего API может проверить его без поиска пользователя в базе. Для большинства API подойдёт токены JWT bearer, часто выдаваемые поставщиком идентификации через OAuth 2.0 или OpenID Connect:
builder.Services
.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(opts =>
{
opts.Authority = "https://my-idp.com";
opts.Audience = "my-api";
});

var app = builder.Build();

app.UseAuthentication();
app.UseAuthorization();

Клиент отправляет токен в заголовке Authorization: Bearer <token> в каждом запросе. Ваш API проверяет его и считывает идентификационные данные пользователя из утверждений токена — никакого хранилища сессий, никаких «липких» сессий, никакого масштабируемого состояния на стороне сервера. Это делает ваш API «не сохраняющим состояние» и упрощает горизонтальное масштабирование.
См. также про референтные токены и отзыв токенов.

3. Проверка подписи JWT, издателя, аудитории и срока действия
Токен безопасен только после проверки того, кто его выпустил, для кого он предназначен, что он не истёк и что его подпись действительна. Настройте эти проверки явно через TokenValidationParameters, а не доверяйте значениям по умолчанию фреймворка:
.AddJwtBearer(opts =>
{
opts.TokenValidationParameters =
new TokenValidationParameters
{
ValidateIssuer = true,
ValidIssuer = "https://my-idp.com",

ValidateAudience = true,
ValidAudience = "my-api",

ValidateIssuerSigningKey = true,
IssuerSigningKey = new SymmetricSecurityKey(key),

ValidateLifetime = true,
ClockSkew = TimeSpan.FromSeconds(30)
};
});

Каждый флаг закрывает лазейку:
- ValidateIssuerSigningKey подтверждает подпись — никогда не отключайте этот параметр, иначе кто угодно сможет подделать токен;
- ValidateIssuer и ValidateAudience гарантируют, что токен получен от вашего поставщика идентификации и предназначен для вашего API, а не для какого-то другого сервиса;
- ValidateLifetime отклоняет просроченные токены.
- ClockSkew - существует для того, чтобы допускать небольшие расхождения во времени между серверами, но его значение по умолчанию составляет целых 5 минут, поэтому просроченный токен может приниматься ещё до 5 минут. Сокращение параметра до 30 секунд или даже до 0 ужесточает контроль за истечением срока действия токенов, при условии синхронизации часов ваших серверов (с помощью NTP).

Продолжение следует…

Источник:
https://antondevtips.com/blog/rest-api-security-best-practices-in-aspnetcore
  • 👍 10
More from @netdeveloperdiary
  1. Sep 26, 2026День 2796. #ЗаметкиНаПолях #AI Рабочий процесс с Copilot для .NET. Продолжение Начало Три…
  2. Sep 25, 2026День 2795. #ЗаметкиНаПолях #AI Рабочий процесс с Copilot для .NET. Начало Проблема с позиц…
  3. Sep 24, 2026День 2794. #Оффтоп #Здоровье Сегодня будет необычный пост. Завтра в Москве стартует конфер…
  4. Sep 23, 2026День 2793. #ЗаметкиНаПолях #SQL 10 Редких Возможностей SQL, Которые Стоит Знать Каждому. Ч…
  5. Sep 22, 2026День 2792. #ЗаметкиНаПолях #SQL 10 Редких Возможностей SQL, Которые Стоит Знать Каждому. Ч…
  6. Sep 21, 2026🔍Тестовое собеседование с Senior C# разработчиком уже завтра 22 сентября(уже завтра!) в 1…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →