Две новости из мира безопасности
Сегодня у меня есть две вещи, которыми хочется поделиться. Первая - хочу познакомить еще с одним проектом OWASP, посвященным вопросам безопасной разработки, https://owasp.org/www-project-top-10-for-business-logic-abuse/# . Когда делаешь свой чек-лист для security code review, можно сделать напоминалки про то, чтобы не забыть чекать авторизацию, не забыть посмотреть, нет ли где ситуации гонок, каких-то вещей еще, которые достоверно не найдет статанализатор. И вот самое сложное (на мой взгляд), это найти и чекнуть потенциальные логические ошибки: какие-то не до конца очевидные пути вычисления, какие-то нетривиальные логические моменты. Да иногда даже и тривиальные. В проекте OWASP Top-10 for Business Logic Abuse авторы собрали как раз топчик категорий именно таких уязвимостей, которые стоит держать в уме. Рекомендую ознакомиться на выходных)
А вторая вещь - это напоминание на случай, если вы забыли, что самая крутая конференция KazHackStan уже открыла регистрацию для пользователей. Ребята все так же верны своим традициям и конференция остается бесплатной, но становится все больше, ярче и круче. И в этом году, как и в прошлом, будет целый день, посвященный безопасной разработке. Регистрируйтесь) https://kazhackstan.com/
Сегодня у меня есть две вещи, которыми хочется поделиться. Первая - хочу познакомить еще с одним проектом OWASP, посвященным вопросам безопасной разработки, https://owasp.org/www-project-top-10-for-business-logic-abuse/# . Когда делаешь свой чек-лист для security code review, можно сделать напоминалки про то, чтобы не забыть чекать авторизацию, не забыть посмотреть, нет ли где ситуации гонок, каких-то вещей еще, которые достоверно не найдет статанализатор. И вот самое сложное (на мой взгляд), это найти и чекнуть потенциальные логические ошибки: какие-то не до конца очевидные пути вычисления, какие-то нетривиальные логические моменты. Да иногда даже и тривиальные. В проекте OWASP Top-10 for Business Logic Abuse авторы собрали как раз топчик категорий именно таких уязвимостей, которые стоит держать в уме. Рекомендую ознакомиться на выходных)
А вторая вещь - это напоминание на случай, если вы забыли, что самая крутая конференция KazHackStan уже открыла регистрацию для пользователей. Ребята все так же верны своим традициям и конференция остается бесплатной, но становится все больше, ярче и круче. И в этом году, как и в прошлом, будет целый день, посвященный безопасной разработке. Регистрируйтесь) https://kazhackstan.com/
owasp.org
OWASP Top 10 for Business Logic Abuse | OWASP Foundation
A very brief, one-line description of your project
👍5🔥2
А есть ли среди вас те, кто пробовал фичу code security review от Claude? Поделитесь мнением - удобно ли это, как сработало, были ли особенности, которые не находились?
https://mostafahussein.medium.com/ai-powered-code-security-reviews-for-devsecops-with-claude-12baeacf196f
https://mostafahussein.medium.com/ai-powered-code-security-reviews-for-devsecops-with-claude-12baeacf196f
Medium
AI-Powered Code Security Reviews for DevSecOps with Claude
Software is being built faster than ever, and that makes it easier for security issues to slip through. That’s why catching flaws early in…
Сегодня предлагаю посмотреть на фргамент реального кода из реальной библиотеки. Этой уязвимости была присвоена CVE, но авторы библиотеки так и не исправили ее, несмотря на попытки владельцев платформы hunter.io добиться исправления. Есть инвайт-линки, по которым пользователь может зарегистрироваться. Но с их обработкой что-то не так, предлагаю вам найти, что. Пишите свои варианты в комментариях.
А код прям такой... #ябытожетакнаписал
А код прям такой... #ябытожетакнаписал
app.post("/invite/:code", async (request, response) => {
const { code } = request.params;
const { username, password } = reqBody(request);
const invite = await Invite.get({ code });
if (!invite || invite.status !== "pending") {
response.status(200).json({ success: false, error: "Invite not found or is invalid." });
return;
}
const { user, error } = await User.create({ username, password, role: "default" });
if (!user) {
response.status(200).json({ success: false, error: "Could not create user." });
return;
}
await Invite.markClaimed(invite.id, user);
response.status(200).json({ success: true, error: null });
});
🔥2❤1
Forwarded from Искусство. Код... ИИ?
Принципы и паттерны безопасной разработки: SRP
Хоть это и не вполне очевидно, но разработка безопасных приложений может (а, возможно, и должна) начинаться, отнюдь не с моделирования угроз, внедрения в код механизмов защиты, ревью безопасности, пентестов, внедрения SCA/SAST/DAST, или, тем более, чего-то, вроде хантовского «Hack Yourself First»✝️ В лучших традициях Shift Left Security, начинать стоит с базовых принципов разработки, таких, как SOLID, YAGNI, DRY, KISS, чистый код с архитектурой и т.п. Именно они позволяют заложить в архитектуру и реализацию приложения правильный фундамент, на котором будет гораздо проще и дешевле реализовывать прочие решения и этапы внедрения DevSecOps.
Начнём с принципа единственной ответственности (Single Responsibility Principle, SRP — первая буква в SOLID), утверждающему, что каждый класс или модуль должен иметь единственную ответственность (только одну причину для изменения). С точки зрения безопасности SRP способствует изолированности компонентов и чётким границам доверия в коде, что существенно облегчает последующую работу с моделью угроз. Когда компонент сконцентрирован на одной задаче, его легче проверять на уязвимости и логические ошибки. Это снижает риск скрытых багов, возникающих при смешении разных обязанностей (например, проверка прав доступа вперемешку с бизнес-логикой). Как отмечают эксперты, соблюдение SRP «ограничивает случайную эскалацию привилегий и упрощает поиск ошибок», а также уменьшает общую поверхность атаки за счёт уменьшения сложности компонентов.
Тривиальный пример: допустим, класс UserAuth одновременно проверяет пароль пользователя и создаёт сессию при входе.
Нарушение SRP может выглядеть так:
В этом коде смешаны проверки безопасности (надежность пароля) и бизнес-логика сессии. Если разработчик решит изменить логику создания сессии, есть риск ненароком ослабить или обойти шаг проверки пароля. Правильнее разделить эти обязанности на отдельные классы (например,
Забавно, что «живым» примером последствий нарушения SRP является одна из наиболее нашумевших уязвимостей в библиотеке логирования Apache Log4j 2 CVE-2021-44228, известная как Log4Shell. Логирование — это задача записи сообщений, но Log4j помимо этого выполнял ещё и роль интерпретатора/поисковика ресурсов (JNDILookup). Фактически, в библиотеку логирования «просочилась» функциональность, выходящая за рамки её единственной ответственности — она не только записывала логи, но и могла выполнять сетевые запросы и загружать код. Если бы Log4j ограничился исключительно записью логов, без вычисления каких-либо lookup-выражений, уязвимость бы не возникла. И действительно, исправление проблемы заключалось в отключении/удалении функции JNDI Lookup из Log4j.
Соблюдение SRP помогает избежать многих CWE, связанных с логическими ошибками и неправильной проверкой условий, которые трудно выявить в нагромождённом коде. Например, SRP предотвращает появление скрытых дефектов управления доступом, из разряда CWE-732, CWE-862, возникающих, когда проверка прав смешана с другими функциями и может быть пропущена.
В целом, SRP укрепляет принцип «secure by design»: мелкие простые модули легче защитить и проверить.
Хоть это и не вполне очевидно, но разработка безопасных приложений может (а, возможно, и должна) начинаться, отнюдь не с моделирования угроз, внедрения в код механизмов защиты, ревью безопасности, пентестов, внедрения SCA/SAST/DAST, или, тем более, чего-то, вроде хантовского «Hack Yourself First»
Начнём с принципа единственной ответственности (Single Responsibility Principle, SRP — первая буква в SOLID), утверждающему, что каждый класс или модуль должен иметь единственную ответственность (только одну причину для изменения). С точки зрения безопасности SRP способствует изолированности компонентов и чётким границам доверия в коде, что существенно облегчает последующую работу с моделью угроз. Когда компонент сконцентрирован на одной задаче, его легче проверять на уязвимости и логические ошибки. Это снижает риск скрытых багов, возникающих при смешении разных обязанностей (например, проверка прав доступа вперемешку с бизнес-логикой). Как отмечают эксперты, соблюдение SRP «ограничивает случайную эскалацию привилегий и упрощает поиск ошибок», а также уменьшает общую поверхность атаки за счёт уменьшения сложности компонентов.
Тривиальный пример: допустим, класс UserAuth одновременно проверяет пароль пользователя и создаёт сессию при входе.
Нарушение SRP может выглядеть так:
class UserAuth {
public Session Authenticate(string username, string password) {
if (!PasswordChecker.IsStrong(password)) {
throw new Exception("Weak password");
}
var user = userRepository.CreateUser(username, password);
return sessionManager.StartSession(user);
}
}В этом коде смешаны проверки безопасности (надежность пароля) и бизнес-логика сессии. Если разработчик решит изменить логику создания сессии, есть риск ненароком ослабить или обойти шаг проверки пароля. Правильнее разделить эти обязанности на отдельные классы (например,
PasswordChecker, UserRepository, SessionManager), а UserAuth сделать оркестратором. Тогда код станет понятнее и безопаснее: каждая часть легко проверяется и тестируется отдельно.Забавно, что «живым» примером последствий нарушения SRP является одна из наиболее нашумевших уязвимостей в библиотеке логирования Apache Log4j 2 CVE-2021-44228, известная как Log4Shell. Логирование — это задача записи сообщений, но Log4j помимо этого выполнял ещё и роль интерпретатора/поисковика ресурсов (JNDILookup). Фактически, в библиотеку логирования «просочилась» функциональность, выходящая за рамки её единственной ответственности — она не только записывала логи, но и могла выполнять сетевые запросы и загружать код. Если бы Log4j ограничился исключительно записью логов, без вычисления каких-либо lookup-выражений, уязвимость бы не возникла. И действительно, исправление проблемы заключалось в отключении/удалении функции JNDI Lookup из Log4j.
Соблюдение SRP помогает избежать многих CWE, связанных с логическими ошибками и неправильной проверкой условий, которые трудно выявить в нагромождённом коде. Например, SRP предотвращает появление скрытых дефектов управления доступом, из разряда CWE-732, CWE-862, возникающих, когда проверка прав смешана с другими функциями и может быть пропущена.
В целом, SRP укрепляет принцип «secure by design»: мелкие простые модули легче защитить и проверить.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6
Всем привет! Предлагаю сегодня посмотреть еще на кусочек кода. Мне он нравится тем, что там можно прикопаться по нескольким направлениям, и с точки зрения разработки, и с точки зрения безопасности, но тем не менее, пара агентов именно проблему безопасности здесь увидели далеко не сразу, а с очень конкретными наводящими промтами.
Очень похожая бага была в логике системы начисления бонусов одного из крупных магазинов Астаны в 2021 году, когда в условиях карантина магазины начали быстренько делать свои онлайн версии.
За покупку начисляются баллы, т.е. после того, как пользователь подтвердил получение товара, приложение отправляет запрос на эндпоинт /api/loyalty/earn-points, логика которого описана в коде ниже. Есть продукты в статусе promotion - за них дают чуть больше. Что я как злоумышленник могу сделать здесь?
А еще хочу рассказать про одно очень классное мероприятие, которое 4 октября пройдет в Алматы - OpenSysConf'25 - https://sysconf.io/2025. Уже в седьмой раз соберутся энтузиасты с горящими глазами, которые обсудят кучу разных вопросов, от безопасности (хардкорной), через администрирование и до ИИ. Если Вы базируетесь в Алматы - очень рекомендую посетить, хоть и не смогу в этом году поучаствовать сама.
Очень похожая бага была в логике системы начисления бонусов одного из крупных магазинов Астаны в 2021 году, когда в условиях карантина магазины начали быстренько делать свои онлайн версии.
За покупку начисляются баллы, т.е. после того, как пользователь подтвердил получение товара, приложение отправляет запрос на эндпоинт /api/loyalty/earn-points, логика которого описана в коде ниже. Есть продукты в статусе promotion - за них дают чуть больше. Что я как злоумышленник могу сделать здесь?
@RestController
@RequestMapping("/api/loyalty")
public class LoyaltyController {
@Autowired
private LoyaltyService loyaltyService;
@Autowired
private OrderService orderService;
@PostMapping("/earn-points")
public ResponseEntity<String> earnLoyaltyPoints(@RequestBody EarnPointsRequest request) {
try {
User user = getCurrentUser();
Order order = orderService.getOrder(request.getOrderId());
if (order == null || !order.getUserId().equals(user.getId())) {
return ResponseEntity.badRequest().body("Invalid order");
}
for (OrderItem item : order.getItems()) {
int pointsForItem = (int) (item.getPrice() * 0.01);
loyaltyService.addPoints(user.getId(), pointsForItem);
if (isPromotionalProduct(item.getProductId())) {
loyaltyService.addPoints(user.getId(), pointsForItem * 2);
}
}
return ResponseEntity.ok("Points earned successfully");
} catch (Exception e) {
return ResponseEntity.status(500).body("Error processing points");
}
}
А еще хочу рассказать про одно очень классное мероприятие, которое 4 октября пройдет в Алматы - OpenSysConf'25 - https://sysconf.io/2025. Уже в седьмой раз соберутся энтузиасты с горящими глазами, которые обсудят кучу разных вопросов, от безопасности (хардкорной), через администрирование и до ИИ. Если Вы базируетесь в Алматы - очень рекомендую посетить, хоть и не смогу в этом году поучаствовать сама.
🔥6❤1👍1
Ко(д)тики и безопасность
Всем привет! Предлагаю сегодня посмотреть еще на кусочек кода. Мне он нравится тем, что там можно прикопаться по нескольким направлениям, и с точки зрения разработки, и с точки зрения безопасности, но тем не менее, пара агентов именно проблему безопасности…
Malicious logic loop или о важности идемпотентности в операциях
Уязвимость в таске этого понедельника продолжает серию уязвимостей из OWASP Top-10 бизнес-логики. И как совершенно верно было отмечено в коментариях, проблема заключается в том, что обращение к эндпоинту /earn-points по логике никак не завязано на реальную покупку и может быть вызвано отдельно. Таким образом злоумышленник может "накрутить" бонусные баллы, не совершая покупок, за которые они должны даваться.
У этой операции не соблюдается свойство идемпотентности. Простыми словами, для такого рода эндпоинтов важно, чтобы вне зависимости от того, сколько раз к нему обратятся, баллы были начислены только единожды для каждой покупки. Самое простое решение - добавить контроль, который будет проверять, было ли осуществлено начисление уже или еще нет. Но если подойти к предыдущему предложению критически, то там не хватает одной важной детали - начисление и контроль должны быть атомарными, иначе та же проблема будет возникать в более сложном сценарии с гонками.
Уязвимость в таске этого понедельника продолжает серию уязвимостей из OWASP Top-10 бизнес-логики. И как совершенно верно было отмечено в коментариях, проблема заключается в том, что обращение к эндпоинту /earn-points по логике никак не завязано на реальную покупку и может быть вызвано отдельно. Таким образом злоумышленник может "накрутить" бонусные баллы, не совершая покупок, за которые они должны даваться.
У этой операции не соблюдается свойство идемпотентности. Простыми словами, для такого рода эндпоинтов важно, чтобы вне зависимости от того, сколько раз к нему обратятся, баллы были начислены только единожды для каждой покупки. Самое простое решение - добавить контроль, который будет проверять, было ли осуществлено начисление уже или еще нет. Но если подойти к предыдущему предложению критически, то там не хватает одной важной детали - начисление и контроль должны быть атомарными, иначе та же проблема будет возникать в более сложном сценарии с гонками.
🔥4
Forwarded from PWN AI (Artyom Semenov)
Почему LLM всё ещё генерируют уязвимый код. Результаты A.S.E Benchmark
В недавнем исследовании был представлен бенчмарк A.S.E (AI Code Generation Security Evaluation), который оценивает способность языковых моделей генерировать безопасный код в условиях, максимально приближённых к реальной разработке. В этом посте мы разберём: чем A.S.E отличается от предыдущих подходов, какие результаты он показал на ведущих моделях и почему они до сих пор уязвимы.
Главное отличие A.S.E в том, что проверка проводится на уровне целого репозитория, а не как это было раньше, на отдельных участках кода. Это позволяет учитывать архитектуру проекта, взаимосвязь файлов и внешние зависимости. Основой для бенчмарка стали реальные репозитории в GitHub с зафиксированными CVE и опубликованными патчами.
Чтобы избежать банального запоминания шаблонов небезопасного кода, разработчики бенчмарка добавили семантические и структурные мутации уязвимостей. Ещё одна важная деталь — автоматическая проверка с помощью правил статического анализа, которые отслеживают источник уязвимости, пути распространения данных и точку эксплуатации, что делает бенчмарк ближе к условиям, которые можно встретить при реальной разработке.
Результаты оказались показательными.
Среди 26 протестированных моделей ни одна не достигла уровня, который бы позволял назвать модель “Best FOR Security Generated CODE”. Лучший общий результат продемонстрировал Claude-3.7-Sonnet, однако его показатели по безопасности существенно отставали от качества кода. При этом наивысший балл именно по безопасности получила модель Qwen3-235B-A22B-Instruct, что указывает на сближение открытых и проприетарных решений в этой области. Самое впечатляющее — reasoning-режимы не помогали исправлять уязвимости, а делали код менее безопасным. Самой проблемной категорией уязвимостей оказался Path Traversal: почти все модели систематически ошибались при обработке путей и проверке доступа к файлам.
На мой взгляд, ценность A.S.E заключается именно в том, что он вскрывает технические слабости LLM, которые не видны на синтетических бенчмарках (хотя, к слову, их сейчас стало заметно меньше). Эти слабости отражают важную проблему: модели хорошо справляются с синтаксисом и общей структурой кода, но по-прежнему не способны достойно учитывать требования безопасности. Я думаю, что в течение года мы увидим заметный прогресс, но пока ситуация остаётся далёкой от уровня, который позволял бы доверять LLM генерацию кода без постоянной проверки.
В недавнем исследовании был представлен бенчмарк A.S.E (AI Code Generation Security Evaluation), который оценивает способность языковых моделей генерировать безопасный код в условиях, максимально приближённых к реальной разработке. В этом посте мы разберём: чем A.S.E отличается от предыдущих подходов, какие результаты он показал на ведущих моделях и почему они до сих пор уязвимы.
Главное отличие A.S.E в том, что проверка проводится на уровне целого репозитория, а не как это было раньше, на отдельных участках кода. Это позволяет учитывать архитектуру проекта, взаимосвязь файлов и внешние зависимости. Основой для бенчмарка стали реальные репозитории в GitHub с зафиксированными CVE и опубликованными патчами.
Чтобы избежать банального запоминания шаблонов небезопасного кода, разработчики бенчмарка добавили семантические и структурные мутации уязвимостей. Ещё одна важная деталь — автоматическая проверка с помощью правил статического анализа, которые отслеживают источник уязвимости, пути распространения данных и точку эксплуатации, что делает бенчмарк ближе к условиям, которые можно встретить при реальной разработке.
Результаты оказались показательными.
Среди 26 протестированных моделей ни одна не достигла уровня, который бы позволял назвать модель “Best FOR Security Generated CODE”. Лучший общий результат продемонстрировал Claude-3.7-Sonnet, однако его показатели по безопасности существенно отставали от качества кода. При этом наивысший балл именно по безопасности получила модель Qwen3-235B-A22B-Instruct, что указывает на сближение открытых и проприетарных решений в этой области. Самое впечатляющее — reasoning-режимы не помогали исправлять уязвимости, а делали код менее безопасным. Самой проблемной категорией уязвимостей оказался Path Traversal: почти все модели систематически ошибались при обработке путей и проверке доступа к файлам.
На мой взгляд, ценность A.S.E заключается именно в том, что он вскрывает технические слабости LLM, которые не видны на синтетических бенчмарках (хотя, к слову, их сейчас стало заметно меньше). Эти слабости отражают важную проблему: модели хорошо справляются с синтаксисом и общей структурой кода, но по-прежнему не способны достойно учитывать требования безопасности. Я думаю, что в течение года мы увидим заметный прогресс, но пока ситуация остаётся далёкой от уровня, который позволял бы доверять LLM генерацию кода без постоянной проверки.
👍8❤1
Prompt Hacking
Долго не писала сюда, но есть две ссылки, которым хочу поделиться.
У learnprompting нашла два курса, которые довольно любопытны с точки зрения того, что суммируют общие подходы к инъекциям в промты. Интересно также повыполнять задания, потестировать инъекции на практике. Ссылки вот:
Интро и продвинутый промт хакинг
А если касательно практики без теории, то рекомендую еще одну игру, где нужно уговорить Гэндальфа рассказать вам секретный пароль (там также доступны другие режимы)
В безопасности моделей очень много схожего с безопасностью кода, что ожидаемо, хоть по сути атак, кажется, несколько больше. По всей видимости, и разбираться с тем, как с ними работать безопасно, тоже придется через опыт атак. И если раньше аппсеки искали всякие площадки типа beewapp или webgoat для демонстрации уязвимостей на коде (ну или придумывали таски, как в этом канале), то теперь аналогичные штуки для атак на модели тоже нужны именно для демонстрации разработчикам, как их будут ломать. Поэтому если знаете еще - будет круто увидеть их в комментариях.
Долго не писала сюда, но есть две ссылки, которым хочу поделиться.
У learnprompting нашла два курса, которые довольно любопытны с точки зрения того, что суммируют общие подходы к инъекциям в промты. Интересно также повыполнять задания, потестировать инъекции на практике. Ссылки вот:
Интро и продвинутый промт хакинг
А если касательно практики без теории, то рекомендую еще одну игру, где нужно уговорить Гэндальфа рассказать вам секретный пароль (там также доступны другие режимы)
В безопасности моделей очень много схожего с безопасностью кода, что ожидаемо, хоть по сути атак, кажется, несколько больше. По всей видимости, и разбираться с тем, как с ними работать безопасно, тоже придется через опыт атак. И если раньше аппсеки искали всякие площадки типа beewapp или webgoat для демонстрации уязвимостей на коде (ну или придумывали таски, как в этом канале), то теперь аналогичные штуки для атак на модели тоже нужны именно для демонстрации разработчикам, как их будут ломать. Поэтому если знаете еще - будет круто увидеть их в комментариях.
Learn Prompting
Intro to Prompt Hacking
Learn about the basics of Prompt Hacking, one of the biggest vulnerabilities in Large Language Models (LLMs), and Prompt Defense techniques.
🔥8👍1
Всем привет!
Что-то давно у нас не было уязвимого кода. Предлагаю посмотреть на следующий фрагмент кода, содержащий логическую уязвимость (или парочку, но связанных с одним и тем же). Как всегда -- при правильном промте и должном уровне настойчивости можно уговорить любого агента разобраться с этим кодом, а сможете ли вы?)
UPD: в комментах классное обсуждение того, что начиная с версии 1.22 ситуация может резко поменяться и в коде останется меньше уязвимостей. Спасибо @nu11by7e
Что-то давно у нас не было уязвимого кода. Предлагаю посмотреть на следующий фрагмент кода, содержащий логическую уязвимость (или парочку, но связанных с одним и тем же). Как всегда -- при правильном промте и должном уровне настойчивости можно уговорить любого агента разобраться с этим кодом, а сможете ли вы?)
package cleaner
import (
"context"
"time"
)
type Store interface {
ListExpired(ctx context.Context, n int) ([]string, error)
Delete(ctx context.Context, id string) error
}
func CleanupExpired(ctx context.Context, db Store) {
t := time.NewTicker(time.Minute)
defer t.Stop()
for {
select {
case <-ctx.Done():
return
case <-t.C:
ids, err := db.ListExpired(ctx, 100)
if err != nil || len(ids) == 0 {
continue
}
for _, id := range ids {
ctx, cancel := context.WithTimeout(ctx, 750*time.Millisecond)
go func(id string) {
defer cancel()
_ = db.Delete(ctx, id)
}(id)
}
}
}
}
UPD: в комментах классное обсуждение того, что начиная с версии 1.22 ситуация может резко поменяться и в коде останется меньше уязвимостей. Спасибо @nu11by7e
👍1
В последнее время даже в этом канале было много призрачного присутствия ИИ, но сегодня хочу поговорить про недавнюю уязвимость в ZYXEL ZLD, Remote Code Execution via CLI Command Injection. А она от высоких технологий очень далека)
Подробно про то, как уязвимость была найдена и что хакер делал для эксплуатации, можно почитать здесь. Но мне бы хотелось обратить внимание на причину -- разработчик счел, что если метод не задокументирован, то можно не заморачиваться над санитизацией. Очень похоже на ситуацию, когда оставляют какой-то служебный или тестовый (иои просто не до конца реализованный) эндпоинт в рассчете на то, что вызова его с фронта нет, значит, и проблемы нет.
Но это не так: все, к чему вы, как разработчик или тестировщик, можете обратиться в вашем приложении без полноценного RBAC (role-based access control), точно так же доступно злоумышленнику. И почему-то, несмотря на использование всяких передовых технологий, количество таких уязвимостей не уменьшается, а встречается все так же часто.
Надеюсь, вам понравится статья, она легко читается)
Подробно про то, как уязвимость была найдена и что хакер делал для эксплуатации, можно почитать здесь. Но мне бы хотелось обратить внимание на причину -- разработчик счел, что если метод не задокументирован, то можно не заморачиваться над санитизацией. Очень похоже на ситуацию, когда оставляют какой-то служебный или тестовый (иои просто не до конца реализованный) эндпоинт в рассчете на то, что вызова его с фронта нет, значит, и проблемы нет.
Но это не так: все, к чему вы, как разработчик или тестировщик, можете обратиться в вашем приложении без полноценного RBAC (role-based access control), точно так же доступно злоумышленнику. И почему-то, несмотря на использование всяких передовых технологий, количество таких уязвимостей не уменьшается, а встречается все так же часто.
Надеюсь, вам понравится статья, она легко читается)
Rainpwn
CVE-2025-8078: Remote Code Execution via CLI Command Injection
An undocumented parameter of the "web-auth" command could allow an authenticated attacker to execute commands remotely due to improper input sanitization, potentially resulting in full device compromise.
👍3🔥1
Сегодня предлагаю посмотреть на фрагмент кода реального проекта (с реальной уязвимостью, CVE и всеми делами) и попробовать угадать, в чем заключается уязвимость. А может, даже угадать, о каком проекте идет речь, благо, CVE свежая и можно посмотреть новости.
Где
Уязвимость оценена в CVSS 9.8, но отчасти причиной тому служит факт, что ассоциирована она с development сервером, а не с боевой средой. Но сам факт такой очевидной баги в боевом проекте впечатляет. Расскажу подробнее о том, что же там скрывается на самом деле, в эту пятницу.
async function openURLMiddleware(req: IncomingMessage, ...) {
if (req.method === 'POST') {
/* ... */
const {url} = req.body as {url: string};
await open(url);
/* ... */
}
next();
}
export default connect().use(json()).use(openURLMiddleware);
Где
open импортируется отсюда: https://github.com/sindresorhus/open/tree/v6.4.0 (прикольно, когда по имени владельца репозитория в голове сразу всплывает ассоциация, что уже в истории были атаки на разработчиков посредством npm зависимостей, опубликованных с аккаунта, отличающегося одной буквой. Вот это популярность, я считаю). Lумаю, что по коду будет понятна причина уязвимости, но сама уязвимость, если вы не читали эту новость, может удивить серьезностью.Уязвимость оценена в CVSS 9.8, но отчасти причиной тому служит факт, что ассоциирована она с development сервером, а не с боевой средой. Но сам факт такой очевидной баги в боевом проекте впечатляет. Расскажу подробнее о том, что же там скрывается на самом деле, в эту пятницу.
GitHub
GitHub - sindresorhus/open at v6.4.0
Open stuff like URLs, files, executables. Cross-platform. - sindresorhus/open
👍1
31 октября рассказывали страшные истории разработчикам про то, как их атакуют. Половина историй так или иначе касалась npm. А часть из них - кражи аккаунтов контрибьюторов популярных библиотек.И вот хорошая новость, если заглянуть на npmjs.com, то увидите такую картинку)
🔥2
OWASP Top-10 обновился! ☄️
Точнее, вышел новый релиз кандидат. Но по факту, можно считать, что обновился. Три новых категории, четыре сменили имя и область применения. Я думаю, что в ближайший месяц есть смысл подробнее и пристальнее посмотреть на изменения - если хотите, присоединяйтесь, будем делать это вместе здесь.
Но поскольку в последнее время мне лично все чаще приходится бороться с процессами(вот неожиданность-то, оказывается, основная проблема для безопасной разработки - это процессы, а не фрагменты кода с уязвимостями, кто бы мог подумать!) , то хочу начать разбор с одного из самых первых документов старой версии - раздела How to use the OWASP Top 10 as a standard.
И вот важный момент, про который часто забывают - это скорее awareness документ. Т.е. его содержимое - это то, о чем в целом знать и держать это в голове нужно постоянно. Это bare minimum для процесса написания кода, ревью кода и создания чеклистов для peer review. А также для выбора инструментов, как ни странно (хотя, как мы помним, многие "логические" баги с инструментами без мышления не ловятся. С условным "мышлением" пока что тоже, но это детали.)
В общем, предлагаю поразбираться в ближайшее время детальнее, что же изменилось, и в чем причины перемен, а пока - вот ссылка на сам документ.
Точнее, вышел новый релиз кандидат. Но по факту, можно считать, что обновился. Три новых категории, четыре сменили имя и область применения. Я думаю, что в ближайший месяц есть смысл подробнее и пристальнее посмотреть на изменения - если хотите, присоединяйтесь, будем делать это вместе здесь.
Но поскольку в последнее время мне лично все чаще приходится бороться с процессами
И вот важный момент, про который часто забывают - это скорее awareness документ. Т.е. его содержимое - это то, о чем в целом знать и держать это в голове нужно постоянно. Это bare minimum для процесса написания кода, ревью кода и создания чеклистов для peer review. А также для выбора инструментов, как ни странно (хотя, как мы помним, многие "логические" баги с инструментами без мышления не ловятся. С условным "мышлением" пока что тоже, но это детали.)
В общем, предлагаю поразбираться в ближайшее время детальнее, что же изменилось, и в чем причины перемен, а пока - вот ссылка на сам документ.
👍7
Ко(д)тики и безопасность
OWASP Top-10 обновился! ☄️ Точнее, вышел новый релиз кандидат. Но по факту, можно считать, что обновился. Три новых категории, четыре сменили имя и область применения. Я думаю, что в ближайший месяц есть смысл подробнее и пристальнее посмотреть на изменения…
Как и договаривались, предлагаю сегодня чуть детальнее поизучать релиз кандидата OWASP Top-10 2025. А на самом деле проговорить некоторые вещи, которые были действительны и для старого.
Существует мапинг между категориями топ-10 и CWE (Common Weakness Enumeration), и в некотором смысле вот эти вот стрелочки с перемещениями означают смену маппинга. И в случае А01:2025 - Broken Access Control, в маппинге произошло добавление категорий и к первому разделу присоединились следующие CWE: CWE-200 (раскрытие чувствительной информации неавторизованному пользователю), CWE-918 (подделка запросов на стороне сервера) и CWE-352 (межсайтовая подделка запросов или CSRF, Cross-Site Request Forgery). Первое: перевод - дело сложное, практически как информация - "чувствительная" , поэтому не судите строго, и второе: в моей картине мира CWE-352 всегда относилась к Broken Access Control, однако, как выяснилось, раньше она стояла в категории «A05:2021 — Security Misconfiguration». CSRF становятся возможны в том числе в случае мисконфигурации CORS - Cross-Origin Resource Sharing политик, которые определяют, как наше приложение будет реагировать на браузерные запросы с других Origin.
И вот именно про мисконфигурации CORS и хочу сегодня поговорить. Это не самая увлекательная уязвимость, но есть тонкие детали, и сегодня посмотрим их на примере фреймворка Spring. Суть атаки проста: злоумышленник добивается выполнения действия от имени пользователя и в рамках его сессии, о котором пользователь вообще не в курсе. Например: смена почтового адреса аккаунта, изменение пароля, или — что посерьёзнее — какая-то финансовая операция. Хотя последний пример сейчас встречается значительно реже (года с 2018 я лично таких случаев не видела), первые — вполне ещё происходят. Очень подробное описание сути атаки можно посмотреть здесь.
Бытует мнение, что если приложение не использует куки, то CORS вполне может быть disabled: мол, раз нет куки, то и CSRF невозможен. Но это не так. Даже без куки подвластный злоумышленнику сайт всё равно может отправлять неаутентифицированные запросы к вашему API, а затем анализировать разницу во времени или кодах ответов. Это позволяет:
- выявлять существующие внутренние эндпоинты,
- «прощупывать» архитектуру API через сайд-чейны (XS-Leaks),
- использовать браузер жертвы как бесплатный ботнет для флуд-атак
А ещё есть забавный кейс: пользовательская часть работает на токенах, а для панели администратора — всё ещё используются куки. В такой гибридной схеме отключение CORS уже приводит к реальным рискам CSRF именно для административных операций.
Поэтому даже если официальная документация прямо на странице про CORS говорит, мол, вот вам пример, как выключить CORS вообще, в реальных приложениях делать этого все же не стоит.
Но позволю себе чуть докопаться и до официального «правильного» примера. В нём действительно не хватает пары важных деталей. Например:
-
-
- начиная с Spring Security 5.3 появился очень полезный метод
В общем, будьте осторожны с CORS)
Существует мапинг между категориями топ-10 и CWE (Common Weakness Enumeration), и в некотором смысле вот эти вот стрелочки с перемещениями означают смену маппинга. И в случае А01:2025 - Broken Access Control, в маппинге произошло добавление категорий и к первому разделу присоединились следующие CWE: CWE-200 (раскрытие чувствительной информации неавторизованному пользователю), CWE-918 (подделка запросов на стороне сервера) и CWE-352 (межсайтовая подделка запросов или CSRF, Cross-Site Request Forgery). Первое: перевод - дело сложное
И вот именно про мисконфигурации CORS и хочу сегодня поговорить. Это не самая увлекательная уязвимость, но есть тонкие детали, и сегодня посмотрим их на примере фреймворка Spring. Суть атаки проста: злоумышленник добивается выполнения действия от имени пользователя и в рамках его сессии, о котором пользователь вообще не в курсе. Например: смена почтового адреса аккаунта, изменение пароля, или — что посерьёзнее — какая-то финансовая операция. Хотя последний пример сейчас встречается значительно реже (года с 2018 я лично таких случаев не видела), первые — вполне ещё происходят. Очень подробное описание сути атаки можно посмотреть здесь.
Бытует мнение, что если приложение не использует куки, то CORS вполне может быть disabled: мол, раз нет куки, то и CSRF невозможен. Но это не так. Даже без куки подвластный злоумышленнику сайт всё равно может отправлять неаутентифицированные запросы к вашему API, а затем анализировать разницу во времени или кодах ответов. Это позволяет:
- выявлять существующие внутренние эндпоинты,
- «прощупывать» архитектуру API через сайд-чейны (XS-Leaks),
- использовать браузер жертвы как бесплатный ботнет для флуд-атак
А ещё есть забавный кейс: пользовательская часть работает на токенах, а для панели администратора — всё ещё используются куки. В такой гибридной схеме отключение CORS уже приводит к реальным рискам CSRF именно для административных операций.
Поэтому даже если официальная документация прямо на странице про CORS говорит, мол, вот вам пример, как выключить CORS вообще, в реальных приложениях делать этого все же не стоит.
Но позволю себе чуть докопаться и до официального «правильного» примера. В нём действительно не хватает пары важных деталей. Например:
-
setAllowedHeaders — помогает быстрее находить проблемы, если приложение использует кастомные заголовки;-
setMaxAge — улучшает производительность, если вы хотите кэшировать preflight-запросы;- начиная с Spring Security 5.3 появился очень полезный метод
setAllowedOriginPatterns, который значительно упрощает жизнь, если необходимо разрешать доступ для целых групп доменов (например, всех субдоменов).В общем, будьте осторожны с CORS)
portswigger.net
What is CSRF (Cross-site request forgery)? Tutorial & Examples | Web Security Academy
In this section, we'll explain what cross-site request forgery is, describe some examples of common CSRF vulnerabilities, and explain how to prevent CSRF ...
🔥6❤🔥2❤1
Уязвимость из сегодняшнего примера трудно классифицировать. Не инъекция, не BOLA, что-то совсем другое. Я бы отнесла ее к уязвимостям бизнес-логики, но она не то чтобы про логику.
Очень абстрактная подсказка: Intel когда-то упустила проблему примерно из той же области и заплатила за это 475 миллионов долларов в 95 году .
И вопрос будет не тот, который обычно задаю. Понятно, что с кодом что-то не так, если уж он в этом канале. Давайте поменяем вопрос: какой сценарий атаки?)
UPD. 100 - минимальная цена, при которой скидка применяется
Очень абстрактная подсказка: I
И вопрос будет не тот, который обычно задаю. Понятно, что с кодом что-то не так, если уж он в этом канале. Давайте поменяем вопрос: какой сценарий атаки?)
UPD. 100 - минимальная цена, при которой скидка применяется
public class DiscountService {
private static final double MIN_PRICE = 100.00;
public boolean isPromoEligible(double purchaseAmount) {
return purchaseAmount >= MIN_PRICE;
}
public double applyDiscount(double price) {
if (isPromoEligible(price)) {
return price - 10.00; // flat discount
}
return price;
}
}
Итак, разбор уязвимости этой недели - атака через точность чисел с плавающей точкой.
Как верно подметили в комментах, основная проблема этого кода -- ошибки округления, на которые все очень часто забивают. Код максимально топорный: берем сумму заказа, если она больше или равна 100, применяем скидку в 10 денежных единиц. Казалось бы, простая задача, но все же уязвимость закралась. Как же так?
А вся проблема в double. Машины хранят числа с ограниченной точностью, очевидно, и операции с плаващей точкой подчиняются стандарту IEEE 754. На скриншоте ниже приведен пример того, как эта штука работает - условно говоря, 100.00 и 99.99999999999999999997 для машины... одно и то же, если выбран неподходящий тип.
А теперь давайте представим, что речь идет о 100 и 99.99999999999999999997 долларах и о том, что эта операция может производиться, ну, к примеру, миллион раз в сутки на протяжении десятилетия. И подвержены проблеме, по сути, все языки, имеющие float и double типы. Но точно так же во всех языках настоятельно не рекомендуется применять эти типы для финансовых операций и в целом для всего, что требует высокой точности. Но есть примеры того, что использовать стоит - Java - BigDecimal, Python - Decimal, Go - big.Float - но делать это нужно явно.
Я помню, еще на курсе ассемблера в универе нам рассказывали о кейсах, когда из-за переполнений и погрешностей вычислений падали самолеты. Но найти именно ту историю не вышло, зато вот история о взрыве ракеты Ariane 5 по причине хоть и не такой же в точности, но схожей.
Как верно подметили в комментах, основная проблема этого кода -- ошибки округления, на которые все очень часто забивают. Код максимально топорный: берем сумму заказа, если она больше или равна 100, применяем скидку в 10 денежных единиц. Казалось бы, простая задача, но все же уязвимость закралась. Как же так?
А вся проблема в double. Машины хранят числа с ограниченной точностью, очевидно, и операции с плаващей точкой подчиняются стандарту IEEE 754. На скриншоте ниже приведен пример того, как эта штука работает - условно говоря, 100.00 и 99.99999999999999999997 для машины... одно и то же, если выбран неподходящий тип.
А теперь давайте представим, что речь идет о 100 и 99.99999999999999999997 долларах и о том, что эта операция может производиться, ну, к примеру, миллион раз в сутки на протяжении десятилетия. И подвержены проблеме, по сути, все языки, имеющие float и double типы. Но точно так же во всех языках настоятельно не рекомендуется применять эти типы для финансовых операций и в целом для всего, что требует высокой точности. Но есть примеры того, что использовать стоит - Java - BigDecimal, Python - Decimal, Go - big.Float - но делать это нужно явно.
Я помню, еще на курсе ассемблера в универе нам рассказывали о кейсах, когда из-за переполнений и погрешностей вычислений падали самолеты. Но найти именно ту историю не вышло, зато вот история о взрыве ракеты Ariane 5 по причине хоть и не такой же в точности, но схожей.
Owl Tutors
Computer Science: The coding error that blew up a rocket
Computer Science: The coding error that blew up a rocket - Owl Tutors
🔥4
Когда ты пентестер и выходит бага на 10.0 - это прикольно. Когда ты аппсек, думаешь - "приехали". А кто еще не видел - RCE на 10.0 в React Server Components, аффектит все, где компоненты включены.
от авторов: https://react.dev/blog/2025/12/03/critical-security-vulnerability-in-react-server-components
от wiz: https://www.wiz.io/blog/critical-vulnerability-in-react-cve-2025-55182
а ссылку на PoC публиковать не буду.
от авторов: https://react.dev/blog/2025/12/03/critical-security-vulnerability-in-react-server-components
от wiz: https://www.wiz.io/blog/critical-vulnerability-in-react-cve-2025-55182
а ссылку на PoC публиковать не буду.
react.dev
Critical Security Vulnerability in React Server Components – React
The library for web and native user interfaces
❤4👍2