Автор статьи разбирает лучшие практики безопасности REST API в ASP.NET Core.
За годы работы он выпустил и проверил множество .NET API и собрал 18 практик, которые, по его опыту, постоянно помогают держать такие системы безопасными.
В статье есть примеры кода и разбор HTTPS, JWT, политик авторизации, принципа минимальных привилегий, валидации входных данных, защиты от over-posting, ограничения размера запросов, параметризованных запросов и EF Core, rate limiting, CORS, CSRF, хранения секретов, логирования и других базовых мер.
Антон также предлагает сохранить статью как
По его словам, количество найденных проблем может удивить.
👉 @KodBlog
За годы работы он выпустил и проверил множество .NET API и собрал 18 практик, которые, по его опыту, постоянно помогают держать такие системы безопасными.
В статье есть примеры кода и разбор HTTPS, JWT, политик авторизации, принципа минимальных привилегий, валидации входных данных, защиты от over-posting, ограничения размера запросов, параметризованных запросов и EF Core, rate limiting, CORS, CSRF, хранения секретов, логирования и других базовых мер.
Антон также предлагает сохранить статью как
dotnet-security-review-skill для ИИ-агентов и прогнать по ней существующую кодовую базу.По его словам, количество найденных проблем может удивить.
Please open Telegram to view this post
VIEW IN TELEGRAM
Anton Dev Tips
REST API Security Best Practices in ASP.NET Core
18 REST API security best practices in ASP.NET Core - HTTPS, JWT validation, authorization policies, rate limiting, CORS, secrets, security headers, and more - each with C# code you can apply today.
❤7🍾1
Летняя уборка в базе данных. Теперь пора посмотреть на сами запросы.
Включаем
Если вы используете Crunchy Bridge, расширение уже доступно по умолчанию и можно сразу переходить к
При самостоятельном размещении нужно изменить
Можно указать
Затем включаем расширение для нужной базы
Ищем дорогие запросы
Для такой проверки обычно полезнее смотреть на суммарное время выполнения. Запрос средней тяжести, который вызывается миллионы раз, часто наносит больше вреда, чем один редкий медленный запрос.
Также стоит смотреть на среднее время и количество строк. Например, последовательное сканирование может проявиться как большое
Что означают столбцы
•
•
•
•
Статистика копится до ручного сброса
Важно помнить, что сброс удаляет всю накопленную историю. Для анализа можно либо сбросить статистику перед заранее известным периодом высокой нагрузки, либо сравнивать текущие данные с сохранённым ранее снимком.
Что делать с найденными запросами
1. Запустить
2. Проверить недостающие индексы, сбросы на диск из-за
3. После деплоя или добавления индекса сбросить статистику, дать системе поработать под реальной нагрузкой и проверить, уменьшилось ли суммарное время выполнения.
👉 @KodBlog
pg_stat_statements отслеживает форму запросов, количество вызовов и время выполнения по всей базе. Это самый короткий путь от «база почему-то тормозит» до «вот эти пять запросов съедают большую часть времени».Включаем
pg_stat_statementsЕсли вы используете Crunchy Bridge, расширение уже доступно по умолчанию и можно сразу переходить к
CREATE EXTENSION.При самостоятельном размещении нужно изменить
postgresql.conf и перезапустить PostgreSQLshared_preload_libraries = 'pg_stat_statements, ...'
pg_stat_statements.track = top
Можно указать
top или all. Режим all также учитывает запросы внутри функций и процедур. top используется по умолчанию и отслеживает только запросы, выполняемые клиентами.Затем включаем расширение для нужной базы
CREATE EXTENSION IF NOT EXISTS pg_stat_statements;
Ищем дорогие запросы
Для такой проверки обычно полезнее смотреть на суммарное время выполнения. Запрос средней тяжести, который вызывается миллионы раз, часто наносит больше вреда, чем один редкий медленный запрос.
SELECT
round(total_exec_time::numeric, 1) AS total_ms,
calls,
round(mean_exec_time::numeric, 2) AS mean_ms,
rows,
query
FROM pg_stat_statements
ORDER BY total_exec_time DESC
LIMIT 20;
Также стоит смотреть на среднее время и количество строк. Например, последовательное сканирование может проявиться как большое
total_exec_time и большое значение rows у запроса, который в норме должен находить одну конкретную запись.Что означают столбцы
•
calls — сколько раз запрос выполнялся с момента последнего сброса статистики•
total_exec_time и mean_exec_time — суммарное и среднее время выполнения в миллисекундах•
rows — общее количество полученных или изменённых строк•
query — нормализованный запрос с параметрами вида $1Статистика копится до ручного сброса
SELECT pg_stat_statements_reset();
Важно помнить, что сброс удаляет всю накопленную историю. Для анализа можно либо сбросить статистику перед заранее известным периодом высокой нагрузки, либо сравнивать текущие данные с сохранённым ранее снимком.
Что делать с найденными запросами
1. Запустить
EXPLAIN с реальными параметрами. pg_stat_statements показывает форму запроса, но не план выполнения.2. Проверить недостающие индексы, сбросы на диск из-за
work_mem и слишком большое количество мелких запросов приложения вроде N+1.3. После деплоя или добавления индекса сбросить статистику, дать системе поработать под реальной нагрузкой и проверить, уменьшилось ли суммарное время выполнения.
Please open Telegram to view this post
VIEW IN TELEGRAM
🍾1
Микросервисы сильно изменили то, как мы создаём и масштабируем приложения.
Но микросервисные системы очень динамичны. Сервисы могут появляться и исчезать, масштабироваться вверх и вниз и даже перемещаться внутри инфраструктуры.
И здесь возникает проблема. Как сервисам находить друг друга и надёжно взаимодействовать?
Жёстко прописывать IP-адреса и порты — плохая идея. Если экземпляр сервиса сменит адрес или появится новый, система может просто перестать работать.
Для этого и нужен Service Discovery.
Он работает как центральный каталог микросервисов. Сервисы регистрируют в нём своё местоположение, а другие сервисы могут через него находить нужные экземпляры и подключаться к ним.
👉 @KodBlog
Но микросервисные системы очень динамичны. Сервисы могут появляться и исчезать, масштабироваться вверх и вниз и даже перемещаться внутри инфраструктуры.
И здесь возникает проблема. Как сервисам находить друг друга и надёжно взаимодействовать?
Жёстко прописывать IP-адреса и порты — плохая идея. Если экземпляр сервиса сменит адрес или появится новый, система может просто перестать работать.
Для этого и нужен Service Discovery.
Он работает как центральный каталог микросервисов. Сервисы регистрируют в нём своё местоположение, а другие сервисы могут через него находить нужные экземпляры и подключаться к ним.
Please open Telegram to view this post
VIEW IN TELEGRAM
❤4🔥2🍾1
Улучшения производительности в .NET 10
https://devblogs.microsoft.com/dotnet/performance-improvements-in-net-10/
👉 @KodBlog
https://devblogs.microsoft.com/dotnet/performance-improvements-in-net-10/
Please open Telegram to view this post
VIEW IN TELEGRAM
Microsoft News
Performance Improvements in .NET 10
Take a tour through hundreds of performance improvements in .NET 10.
🍾1
Вот хороший пример использования перехватчиков EF:
— Отслеживание времени создания и изменения сущностей.
Через ChangeTracker можно проверить состояние сущности и заполнить соответствующие поля.
Если этот DbContext всегда используется в рамках HTTP-запроса, можно также передавать UserId.
👉 @KodBlog
— Отслеживание времени создания и изменения сущностей.
Через ChangeTracker можно проверить состояние сущности и заполнить соответствующие поля.
Если этот DbContext всегда используется в рамках HTTP-запроса, можно также передавать UserId.
Please open Telegram to view this post
VIEW IN TELEGRAM
🍾1
Как сохранять объекты-значения в EF?
Допустим, у сущности
EF позволяет настроить его как owned type, принадлежащий этой сущности. В результате
👉 @KodBlog
Допустим, у сущности
Apartment есть Address, который вы реализовали как объект-значение.EF позволяет настроить его как owned type, принадлежащий этой сущности. В результате
Apartment и Address будут храниться в одной таблице базы данных, что может повысить производительность.Please open Telegram to view this post
VIEW IN TELEGRAM
🔥5🍾1
Проводник — это место, где проходит огромная часть повседневной работы в Windows.
Открытие папок. Переименование файлов. Переключение между локальными и облачными данными. Правый клик, чтобы перейти к следующему действию. Когда всё это работает медленно, зависает или перегружено лишними элементами — это сразу заметно.
В сегодняшней сборке Windows Insider Microsoft ускорила запуск Проводника, сократила количество зависаний и задержек, улучшила мелкие повседневные детали и переработала контекстное меню по правому клику — теперь оно проще, быстрее и лучше настраивается.
Подробнее:
https://blogs.windows.com/windows-insider/2026/08/17/improving-file-explorer-context-menu-faster-simpler-and-more-customizable/
👉 @KodBlog
Открытие папок. Переименование файлов. Переключение между локальными и облачными данными. Правый клик, чтобы перейти к следующему действию. Когда всё это работает медленно, зависает или перегружено лишними элементами — это сразу заметно.
В сегодняшней сборке Windows Insider Microsoft ускорила запуск Проводника, сократила количество зависаний и задержек, улучшила мелкие повседневные детали и переработала контекстное меню по правому клику — теперь оно проще, быстрее и лучше настраивается.
Подробнее:
https://blogs.windows.com/windows-insider/2026/08/17/improving-file-explorer-context-menu-faster-simpler-and-more-customizable/
Please open Telegram to view this post
VIEW IN TELEGRAM
❤3🤣1🍾1
Импортируете CSV в Postgres? Используйте
Это быстро, потому что данные передаются одной массовой командой с минимальным количеством обменов по протоколу, одним разбором и планированием, прямым преобразованием строк и без накладных расходов на отдельный запрос для каждой строки.
Что важно знать:
Включает стандартный разбор CSV: запятые, поля в кавычках и экранированные кавычки.
Список целевых столбцов
Порядок столбцов в CSV редко совпадает с таблицей. Всегда указывайте целевые столбцы в том порядке, в котором они идут в файле. Postgres сопоставляет их по позиции, а не по имени из заголовка CSV.
Пропускает строки заголовка. Обычный
Позволяет сопоставить специальную строку в CSV, например
Неуказанные столбцы
Столбцы таблицы, которые не указаны в списке целевых столбцов, автоматически получают
Лишние столбцы в CSV
Postgres выдаст ошибку, если в CSV больше полей, чем указано целевых столбцов. Обрежьте файл или сначала загрузите данные в более широкую промежуточную таблицу.
NULL-значения
В формате
Обработка ошибок через
Исторически
•
•
•
👉 @KodBlog
COPY или \copy.Это быстро, потому что данные передаются одной массовой командой с минимальным количеством обменов по протоколу, одним разбором и планированием, прямым преобразованием строк и без накладных расходов на отдельный запрос для каждой строки.
Что важно знать:
FORMAT csvВключает стандартный разбор CSV: запятые, поля в кавычках и экранированные кавычки.
Список целевых столбцов
Порядок столбцов в CSV редко совпадает с таблицей. Всегда указывайте целевые столбцы в том порядке, в котором они идут в файле. Postgres сопоставляет их по позиции, а не по имени из заголовка CSV.
HEADER / HEADER nПропускает строки заголовка. Обычный
HEADER пропускает первую строку. Ожидается, что Postgres 19 позволит передавать число, например HEADER 2, чтобы пропускать несколько начальных строк.DEFAULT 'string'Позволяет сопоставить специальную строку в CSV, например
'__DEFAULT__', с выражением DEFAULT соответствующего столбца.Неуказанные столбцы
Столбцы таблицы, которые не указаны в списке целевых столбцов, автоматически получают
DEFAULT или NULL.Лишние столбцы в CSV
Postgres выдаст ошибку, если в CSV больше полей, чем указано целевых столбцов. Обрежьте файл или сначала загрузите данные в более широкую промежуточную таблицу.
NULL-значения
В формате
csv стандартным представлением NULL является пустая строка без кавычек. Это можно изменить через NULL 'string'.Обработка ошибок через
ON_ERROR и REJECT_LIMITИсторически
COPY останавливался на первой ошибке преобразования. В новых версиях появились:•
ON_ERROR ignore в Postgres 17 — пропускает некорректные строки и сообщает их количество•
REJECT_LIMIT n в Postgres 18 — задаёт максимальное число плохих строк при ON_ERROR ignore, после которого импорт будет остановлен•
ON_ERROR set_null в Postgres 19 — заменяет некорректное поле на NULL вместо того, чтобы отбрасывать всю строкуPlease open Telegram to view this post
VIEW IN TELEGRAM
🔥1🍾1
Разработчик предложил официальную формальную семантику C# на Lean 4 — то есть основу, которая позволит строить машинно проверяемые доказательства для C#.
ИИ-агенты становятся очень хороши в написании кода — и очень хороши в том, чтобы его ломать.
В эпоху агентов для критически важного ПО фразы «тесты прошли» будет уже недостаточно. Нам нужно уметь доказывать свойства кода, который мы выпускаем.
И это уже становится практичным.
У Rust уже есть Aeneas → Lean. Microsoft Research использует его для формальной верификации SymCrypt. У Java и C тоже уже есть основа в формальной верификации.
C# не должен остаться позади.
ИИ может написать код.
ИИ может построить доказательство.
А детерминированное ядро проверки доказательств проверит, действительно ли это доказательство корректно.
Это совсем другая модель доверия по сравнению с
ИИ пишет код → ИИ проверяет код → надеемся, что оба оказались правы.
Предложение: https://github.com/dotnet/csharplang/discussions/10314
👉 @KodBlog
ИИ-агенты становятся очень хороши в написании кода — и очень хороши в том, чтобы его ломать.
В эпоху агентов для критически важного ПО фразы «тесты прошли» будет уже недостаточно. Нам нужно уметь доказывать свойства кода, который мы выпускаем.
И это уже становится практичным.
У Rust уже есть Aeneas → Lean. Microsoft Research использует его для формальной верификации SymCrypt. У Java и C тоже уже есть основа в формальной верификации.
C# не должен остаться позади.
ИИ может написать код.
ИИ может построить доказательство.
А детерминированное ядро проверки доказательств проверит, действительно ли это доказательство корректно.
Это совсем другая модель доверия по сравнению с
ИИ пишет код → ИИ проверяет код → надеемся, что оба оказались правы.
Предложение: https://github.com/dotnet/csharplang/discussions/10314
Please open Telegram to view this post
VIEW IN TELEGRAM
GitHub
Proposal: An official Lean formal semantics for C# · dotnet csharplang · Discussion #10314
This is not a proposal for new C# syntax or language constructs. It is a proposal for language infrastructure: an officially maintained Lean 4 formal semantics for C#, developed incrementally along...
👍2🍾1
Андерс Хейлсберг — создатель TypeScript и C#. На подкасте его спросили о том, как переписывание компилятора на Go позволило ускорить TypeScript примерно в 10 раз, и о том, как ИИ уже влияет на разработку ПО.
В выпуске
• Как переписывание компилятора дало ускорение в 10 раз
• Почему выбрали Go, а не Rust
• Почему для миграции не использовали LLM
• Как ИИ повлияет на разработку ПО в будущем
https://www.youtube.com/watch?v=cywK3XYYJ2o
👉 @KodBlog
В выпуске
• Как переписывание компилятора дало ускорение в 10 раз
• Почему выбрали Go, а не Rust
• Почему для миграции не использовали LLM
• Как ИИ повлияет на разработку ПО в будущем
https://www.youtube.com/watch?v=cywK3XYYJ2o
Please open Telegram to view this post
VIEW IN TELEGRAM
YouTube
Creator of TypeScript: 10x Faster Typescript, Why AI Won't Replace SWEs | Anders Hejlsberg
Anders Hejlsberg is the creator of TypeScript and C#, and I asked him about how the TypeScript compiler got 10x faster through a rewrite in Go and his thoughts on how AI has impacted software engineering.
• My ergonomic keyboard project I mentioned, you…
• My ergonomic keyboard project I mentioned, you…
🍾3
C# 14 позволяет объединить проверку на
Раньше нужно было писать так:
Теперь оператор
Поведение то же самое. Если
Ещё несколько нюансов:
— работает и с
— не работает с
— поддерживаются и
👉 @KodBlog
null и присваивание в одну строку.Раньше нужно было писать так:
if (customer is not null)
{
customer.Order = GetCurrentOrder();
}
Теперь оператор
?. можно использовать слева от присваивания:customer?.Order = GetCurrentOrder();
Поведение то же самое. Если
customer равен null, GetCurrentOrder() даже не вызовется.Ещё несколько нюансов:
— работает и с
+=, -= и другими составными присваиваниями— не работает с
++ и --— поддерживаются и
?., и ?[] слева от присваиванияPlease open Telegram to view this post
VIEW IN TELEGRAM
👍16🍾2
C# 14 позволяет массивам,
Массив
✔️ Преобразования работают между
✔️ Типы
✔️ Компилятору стало проще выводить обобщённые типы, когда массивы и
👉 @KodBlog
Span<T> и ReadOnlySpan<T> автоматически преобразовываться друг в друга.Span<T> и ReadOnlySpan<T> уже повсеместно используются в среде выполнения ради производительности без ущерба для безопасности. В C# 14 компилятор получил полноценную поддержку преобразований между ними и T[]:void PrintFirst(ReadOnlySpan<int> values)
{
Console.WriteLine(values[0]);
}
int[] numbers = [10, 20, 30];
PrintFirst(numbers);
Массив
int напрямую передаётся в параметр ReadOnlySpan<int> — никаких явных вызовов преобразования.✔️ Преобразования работают между
ReadOnlySpan<T>, Span<T> и T[]✔️ Типы
Span теперь могут выступать получателями методов расширения✔️ Компилятору стало проще выводить обобщённые типы, когда массивы и
Span используются вместеPlease open Telegram to view this post
VIEW IN TELEGRAM
👍5🍾1
Эти заметки — структурированное руководство по собеседованиям по проектированию систем.
Внутри разбираются как базовые подходы к System Design, так и конкретные архитектуры: веб-краулеры, системы уведомлений, платёжные платформы и другие типичные задачи с собеседований.
https://github.com/liquidslr/system-design-notes
👉 @KodBlog
Внутри разбираются как базовые подходы к System Design, так и конкретные архитектуры: веб-краулеры, системы уведомлений, платёжные платформы и другие типичные задачи с собеседований.
https://github.com/liquidslr/system-design-notes
Please open Telegram to view this post
VIEW IN TELEGRAM
GitHub
GitHub - liquidslr/system-design-notes: Notes of the book System Desgin Interview - An Insider's Guide
Notes of the book System Desgin Interview - An Insider's Guide - liquidslr/system-design-notes