Про атаки на разработчиков
Вчера с одной из команд говорили про социальную инженерию на разработчиков. Вспомнились кейсы, которые периодически активно обсуждаются в сети - когда на фейковом собеседовании человека просят скачать код с какого-то репозитория и на этом живом коде якобы провести сессию лайф-коддинга, чтобы убедиться в его навыках. Проблема начинается в тот момент, когда проект запускается в IDE и обфусцированный фрагмент одной из библиотек обращается к контрольному центру, чтобы скачать... RAT-файл, ратник, или remote access tool. Иными словами - программку, которая позволит выполнить на ПК жертвы определенные действия. В простом варианте атаки, на самом деле, не нужен даже ратник, потому что у нас и так выполняется код и какие-то доступы у него все равно будут.
И тут важный момент - а как защищаться? Можно поделить защиты на два аспекта.
1. Человек.
Это социальная инженерия, как ни крути. Поэтому то, насколько критично человек относится своим действиям, все еще остается важным. Зачастую разработчики и другие IT специалисты более расслабленно воспринимают стандартные правила кибергигиены, и злоумышленники этим пользуются.
2. Процессы и инструменты.
Докер-образы, плагины для IDE и браузеров, библиотеки в ZIP-архивах... как много всего может попасть к нам из непроверенных источников. Иногда по необходимости, иногда просто из любопытства. И все это нужно воспринимать как потенциально вредоносное, иными словами - ограничивать возможности, запускать все недоверенное в изолированных средах, перепроверять, что все это пришло из официальных источников.
И если говорить именно про эту атаку, то не стоит забывать, что IDE тоже пытается вас защитить (хоть полноценный сендбоксинг в ней и не возможен). Так, для плагинов механизм доверия в большинстве случаев реализован через подписывание, а для проектов есть Workspace Trust / Safe Mode, которые призваны ограничить возможности запускаемого кода, если он пришел из стороннего источника.
Вчера с одной из команд говорили про социальную инженерию на разработчиков. Вспомнились кейсы, которые периодически активно обсуждаются в сети - когда на фейковом собеседовании человека просят скачать код с какого-то репозитория и на этом живом коде якобы провести сессию лайф-коддинга, чтобы убедиться в его навыках. Проблема начинается в тот момент, когда проект запускается в IDE и обфусцированный фрагмент одной из библиотек обращается к контрольному центру, чтобы скачать... RAT-файл, ратник, или remote access tool. Иными словами - программку, которая позволит выполнить на ПК жертвы определенные действия. В простом варианте атаки, на самом деле, не нужен даже ратник, потому что у нас и так выполняется код и какие-то доступы у него все равно будут.
И тут важный момент - а как защищаться? Можно поделить защиты на два аспекта.
1. Человек.
Это социальная инженерия, как ни крути. Поэтому то, насколько критично человек относится своим действиям, все еще остается важным. Зачастую разработчики и другие IT специалисты более расслабленно воспринимают стандартные правила кибергигиены, и злоумышленники этим пользуются.
2. Процессы и инструменты.
Докер-образы, плагины для IDE и браузеров, библиотеки в ZIP-архивах... как много всего может попасть к нам из непроверенных источников. Иногда по необходимости, иногда просто из любопытства. И все это нужно воспринимать как потенциально вредоносное, иными словами - ограничивать возможности, запускать все недоверенное в изолированных средах, перепроверять, что все это пришло из официальных источников.
И если говорить именно про эту атаку, то не стоит забывать, что IDE тоже пытается вас защитить (хоть полноценный сендбоксинг в ней и не возможен). Так, для плагинов механизм доверия в большинстве случаев реализован через подписывание, а для проектов есть Workspace Trust / Safe Mode, которые призваны ограничить возможности запускаемого кода, если он пришел из стороннего источника.
BlueGrid.io
Dev Popper: How Social Engineering Exploits Developers with Fake Job Offers
The Dev Popper campaign is a social engineering attack in which attackers pose as recruiters. Read more to learn how to protect ourselves.
🔥2
Что нового в OWASP ASVS 5.0
Если вы забыли, что это, то можно почитать вот тут
В мае вышел новый релиз OWASP ASVS (самый большой за последние пять лет). И, как мне кажется, новая версия стала гораздо удобнее для разработчиков.
Но самое первое, что бросается в глаза, это изменения в области уровней защищенности. Если коротко, ASVS предлагает пачки контролей, соответствующие уровням L1, L2, L3, где L1 - базовая безопасность, а L3 - продвинутый уровень, соответствующий высокой зрелости продукта. Каждый уровень описывается своим набором требований\контролей, которые применяются к коду и, если все требования выполнены, можно считать, что мы соответствуем какому-то уровню.
Так вот. В старой версии ASVS 4.0.3 для соответствия уровню L1 нужно было выполнить 131 условие. В новой - всего 70. И несмотря на кажущееся противоречие (вроде как время идет, средний уровень зрелости должен расти), этот шаг весьма оправдан и является следствием жарких дискуссий. И здесь важно понимать, что высокое количество правил уровня L1, по всей видимости, являлось одной из причин того, что компании, начиная работать с ASVS, либо не доводили до соответствия первому уровню, либо в принципе бросали всю эту затею(все чаще думаю о том, что с безопасностью надо как с аллергеном - сперва малыми дозами, чтобы не вызывало сразу прям отторжения)
А еще все ожидали от этой версии правил работы с продуктами, использующими LLM, и не дождались. Авторы решили, что это заслуживает отдельного стандарта - и вот он .
А вот из реально прикольного - совсем новый раздел про пост-квантовую криптографию и сокращение длины минимально необходимого пароля (прикиньте! но там хитрая формулировка. Раньше было про "минимальную" длину пароля в 12 символов, сейчас стало "минимальная" - 8, а вот рекомендованная - 15. Но вообще, конечно, все уже присматриваются к историям без паролей).
В общем, новый документ ёмче, в нем меньше дублирования, убрано явно устаревшее и неактуальное и складывается ощущение, что новый документ еще больше адпатирован под разработчиков, а не под безопасников. И это не может не радовать.
Если вы забыли, что это, то можно почитать вот тут
В мае вышел новый релиз OWASP ASVS (самый большой за последние пять лет). И, как мне кажется, новая версия стала гораздо удобнее для разработчиков.
Но самое первое, что бросается в глаза, это изменения в области уровней защищенности. Если коротко, ASVS предлагает пачки контролей, соответствующие уровням L1, L2, L3, где L1 - базовая безопасность, а L3 - продвинутый уровень, соответствующий высокой зрелости продукта. Каждый уровень описывается своим набором требований\контролей, которые применяются к коду и, если все требования выполнены, можно считать, что мы соответствуем какому-то уровню.
Так вот. В старой версии ASVS 4.0.3 для соответствия уровню L1 нужно было выполнить 131 условие. В новой - всего 70. И несмотря на кажущееся противоречие (вроде как время идет, средний уровень зрелости должен расти), этот шаг весьма оправдан и является следствием жарких дискуссий. И здесь важно понимать, что высокое количество правил уровня L1, по всей видимости, являлось одной из причин того, что компании, начиная работать с ASVS, либо не доводили до соответствия первому уровню, либо в принципе бросали всю эту затею
А еще все ожидали от этой версии правил работы с продуктами, использующими LLM, и не дождались. Авторы решили, что это заслуживает отдельного стандарта - и вот он .
А вот из реально прикольного - совсем новый раздел про пост-квантовую криптографию и сокращение длины минимально необходимого пароля (прикиньте! но там хитрая формулировка. Раньше было про "минимальную" длину пароля в 12 символов, сейчас стало "минимальная" - 8, а вот рекомендованная - 15. Но вообще, конечно, все уже присматриваются к историям без паролей).
В общем, новый документ ёмче, в нем меньше дублирования, убрано явно устаревшее и неактуальное и складывается ощущение, что новый документ еще больше адпатирован под разработчиков, а не под безопасников. И это не может не радовать.
owasp.org
OWASP Artificial Intelligence Security Verification Standard AISVS Docs | OWASP Foundation
OWASP AI verification standard for developers and testers
🔥6👍1
В последнее время стала часто попадаться либо эта бага, либо близко связанные с ней. Причем не только мне, в статьях и разборах стала тоже часто фигурировать (хотя казалось бы). Предлагаю посмотреть кусочек кода и ответить на вопрос, что с ним не так (там две баги. Одна основная, вторая случайно затесалась). И главное - как такое атаковать.
встречается это дело и в других языках, но пример на Java
@RestController
@RequestMapping("/users")
public class UserController {
@Autowired
private UserRepository userRepo;
@PostMapping
public User createUser(@RequestBody Map<String, Object> payload) {
User user = new User();
user.setUsername((String) payload.get("username"));
user.setPassword((String) payload.get("password"));
if (payload.containsKey("role")) {
user.setRole((String) payload.get("role"));
} else {
user.setRole("USER");
}
return userRepo.save(user);
}
}
встречается это дело и в других языках, но пример на Java
Поскольку в целом как-то нехорошо отделять безопасность приложений от безопасности сред, в которых они запускаются, считаю важным делиться и такими штуками тоже.
Офигенная диаграмма безопасности для k8s, на которую можно ориентироваться при работе со своими кластерами.
https://kubesec-diagram.github.io/
Офигенная диаграмма безопасности для k8s, на которую можно ориентироваться при работе со своими кластерами.
https://kubesec-diagram.github.io/
kubesec-diagram.github.io
Interactive annotated security focused kubernetes diagram.
🔥3👍2
Пятница, а значит, пора разобрать пример, про который писала на этой неделе.
Но перед этим важный комментарий, про который сказали в одном из чатиков - контроль может быть реализован и в других местах. Но чаще всего он не реализован нигде. Как мне кажется, основная задача подобного рода тасков - натренировать глаза видеть потенциально опасные моменты на код ревью. И лучше уж перепроверить, что в другом месте контроль реализовали, а также что он корректен и достаточен, и потом сливать код с чистой совестью.
Если возвращаться к примеру, то в нем есть в том числе вот такой замечательный фрагмент:
Если в запросе от пользователя пришло поле
Уязвимость в примере - чисто логическая, она не задетектится ни статанализатором, ни, будем честны, стандартным процессом QA, если вы заранее с QA не обговаривали, что и такое может случиться. И это тот самый случай, когда чеклисты спасают. Зафиксированные, конкретные чеклисты, содержащие список того, на что обратить внимание.
Более интересный и массовый вариант уязвимости, который может возникнуть в схожем коде, и который получил название Mass Assignement, когда фреймворк дает нам сбайндить параметры запроса напрямую в объекты. И что хорошо - во фреймворках, которые позволяют это сделать, все предусмотрено - всегда есть возможность завайтлистить то, что нам нужно, или заблеклистить.
резюмируя:
1. Код ревью - это такой момент в разработке, когда можно поймать кучу проблем безопасности, непонятных для остальных этапов.
2. Фронт бэку не друг и не товарищ, и наоборот тоже. За свои действия несем ответственность сами и перепроверяем.
3. Инструмент и его возможности всегда надо использовать правильно.
4*. Блэклисты - лучше, чем ничего, вайтлисты - лучше блэклистов.
ну и ссылки
Spring MVC https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/validation/DataBinder.html#setAllowedFields-java.lang.String...-:~:text=custom%20editors%2C%20etc.-,WARNING,-%3A%20Data%20binding%20can
nodeJS https://underscorejs.org/#pick
Python(Django) https://www.coffeeonthekeyboard.com/mass-assignment-security-part-10-855/
PHP Laravel + Eloquent
https://laravel.com/docs/5.2/eloquent#mass-assignment
Но перед этим важный комментарий, про который сказали в одном из чатиков - контроль может быть реализован и в других местах. Но чаще всего он не реализован нигде. Как мне кажется, основная задача подобного рода тасков - натренировать глаза видеть потенциально опасные моменты на код ревью. И лучше уж перепроверить, что в другом месте контроль реализовали, а также что он корректен и достаточен, и потом сливать код с чистой совестью.
Если возвращаться к примеру, то в нем есть в том числе вот такой замечательный фрагмент:
if (payload.containsKey("role")) {
user.setRole((String) payload.get("role"));
} else {
user.setRole("USER");
}
Если в запросе от пользователя пришло поле
role, выставить роль в его значение, иначе сделать роль "USER". И если в этом месте вам хочется спросить "да кто же так пишет", то спешу вас обрадовать - еще как пишут. Например в рассчете на то, что сам запрос корректно сформирует фронт. Уязвимость в примере - чисто логическая, она не задетектится ни статанализатором, ни, будем честны, стандартным процессом QA, если вы заранее с QA не обговаривали, что и такое может случиться. И это тот самый случай, когда чеклисты спасают. Зафиксированные, конкретные чеклисты, содержащие список того, на что обратить внимание.
Более интересный и массовый вариант уязвимости, который может возникнуть в схожем коде, и который получил название Mass Assignement, когда фреймворк дает нам сбайндить параметры запроса напрямую в объекты. И что хорошо - во фреймворках, которые позволяют это сделать, все предусмотрено - всегда есть возможность завайтлистить то, что нам нужно, или заблеклистить.
резюмируя:
1. Код ревью - это такой момент в разработке, когда можно поймать кучу проблем безопасности, непонятных для остальных этапов.
2. Фронт бэку не друг и не товарищ, и наоборот тоже. За свои действия несем ответственность сами и перепроверяем.
3. Инструмент и его возможности всегда надо использовать правильно.
4*. Блэклисты - лучше, чем ничего, вайтлисты - лучше блэклистов.
ну и ссылки
Spring MVC https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/validation/DataBinder.html#setAllowedFields-java.lang.String...-:~:text=custom%20editors%2C%20etc.-,WARNING,-%3A%20Data%20binding%20can
nodeJS https://underscorejs.org/#pick
Python(Django) https://www.coffeeonthekeyboard.com/mass-assignment-security-part-10-855/
PHP Laravel + Eloquent
https://laravel.com/docs/5.2/eloquent#mass-assignment
cheatsheetseries.owasp.org
Mass Assignment - OWASP Cheat Sheet Series
Website with the collection of all the cheat sheets of the project.
👍4🔥2
https://t.me/art_code_ai/11
Попалась статья (в telegraph, но instant view) про то, как можно накосячить при работе со структурированными данными. Прям рекомендую посмотреть не косячит ли парсер, который используете вы в вашем стеке - можно узнать много удивительного.
Попалась статья (в telegraph, но instant view) про то, как можно накосячить при работе со структурированными данными. Прям рекомендую посмотреть не косячит ли парсер, который используете вы в вашем стеке - можно узнать много удивительного.
Telegram
Искусство. Код... ИИ?
Не рассчитывал, что тут сходу появятся посты, не влезающие в тележные 4к символов, и впредь обязательно постараюсь быть сдержаннее... но чёт не удержался: https://telegra.ph/Po-sledam-prostrelennyh-nog-v-parserah-Go-i-ne-tolko-06-21
👍2🔥1
ок, про SQL инъекции можно говорить вечно, но они все равно продолжают встречаться (правда, во все более экзотических местах). Обсуждали тут с друзьями SQL инъекции в Java (естественно, Spring) и вспомнилась статья https://www.baeldung.com/sql-injection
и вот тут важный момент - все вроде запомнили, что не надо конкатенацию делать, но есть и такие приколы:
Spring заинжектит sortField в ORDER BY. Как есть.
и вот тут важный момент - все вроде запомнили, что не надо конкатенацию делать, но есть и такие приколы:
@GetMapping("/users")
public List<User> list(@RequestParam("sort") String sortField) {
return userRepo.findAll(Sort.by(sortField));
}
Spring заинжектит sortField в ORDER BY. Как есть.
Baeldung on Kotlin
SQL Injection and How to Prevent It? | Baeldung
Explore coding mistakes in Java that can lead to a vulnerable application and how to avoid them using the APIs available in the JVM's standard runtime library.
👍2🤔1
Мелкая, но важная деталь
Всем привет! сегодня хочу предложить почитать еще немного уязвимого кода(в этом есть какой-то свой кайф, не правда ли?) . Уязвимость, которая объединяет эти фрагменты, имеет очень низкий уровень критичности. И поэтому ее часто пропускают на код ревью. Проблема обычно всплывает гораздо позже, чем этапы написания, запуска и зачастую даже во время эксплуатации проблема очень хорошо скрывается. Итак, что не так с кодом ниже и как бы вы это проэксплуатировали, будь вы на месте злоумышленника?
Java, Spring
PHP, Laravel
Node.js
.Net
Всем привет! сегодня хочу предложить почитать еще немного уязвимого кода
Java, Spring
@GetMapping("/search")
public void search(@RequestParam String q) {
log.info("User search query: " + q);
}
PHP, Laravel
public function search(Request $request) {
$q = $request->input('q');
Log::info("User search query: $q");
}
Node.js
app.get('/search', (req, res) => {
const q = req.query.q;
console.log("User search query: " + q);
});
.Net
[HttpGet("search")]
public IActionResult Search(string q)
{
_logger.LogInformation("User search query: " + q);
return Ok();
}
🤔5👍4
>>> To address this challenge, GitLab's Vulnerability Research team recently developed an automated detection system designed to proactively identify malicious dependencies in software supply chains
понятное дело, они дают инструменты безопасности у себя в продукте и наверняка вопросами собственной безопасности всерьез озабочены, но какой кайф читать о том, как разработческая компания внутри ведет security исследования. А теперь вопрос к разработчикам в чате (риторический ): у вас в компании SCA работает?) не просто стоит, а прям работает?)
понятное дело, они дают инструменты безопасности у себя в продукте и наверняка вопросами собственной безопасности всерьез озабочены, но какой кайф читать о том, как разработческая компания внутри ведет security исследования. А теперь вопрос к разработчикам в чате (
Forwarded from Бесконечное ИТ
Интересный пост в блоге Gitlab о том, как они обнаружили supply chain attack в модуле для GO. В компании есть своя комбинированная система обнаружения таких атак. Это смесь песочницы, анализа работы кода подключаемого модуля + ревью модуля человеком. Всегда впечатляет когда такие системы конструируются и создаются в компании самостоятельно, это ли не из показатель развитой инженерной культуры.
https://about.gitlab.com/blog/gitlab-catches-mongodb-go-module-supply-chain-attack/
https://about.gitlab.com/blog/gitlab-catches-mongodb-go-module-supply-chain-attack/
about.gitlab.com
GitLab catches MongoDB Go module supply chain attack
Learn how GitLab detected a supply chain attack targeting Go developers through fake MongoDB drivers that deploy persistent backdoor malware.
❤3👍2
Log injections📖
Пришла пятница, значит, пора разобраться с уязвимостью, про которую говорили в начале недели. Хочу немного поговорить о том, что может сделать злоумышленник с этой, на первый взгляд непримечательной, багой.
Если вспомнить методологию моделирования угроз STRIDE, то там есть целый раздел про Repudiation - отрицание того, что что-то произошло. Или как злоумышленник скроет следы. Скрывают их не только для того, чтобы не нашли пользователя (айпишник, вотэвер), с которого произошла атака, но и для того, чтобы не так-то просто было понять, какую уязвимость эксплуатировали. Итак, давайте посмотрим пример:
Злоумышленник может послать такой запрос (ведь его задача "вшить" в полотно логов что-то похожее на обычный лог):
И теперь лог будет выглядеть так:
А что если попробовать такое? А вдруг салертит?
И вот тут важный момент, а что происходит с нашими логами дальше? одно дело, если они молча хранятся какое-то время и никто никогда в них не заглядывает (ц-ц-ц). Если возникнет инцидент и мы до них дойдем, то такими методами атакующий запутает нас. А вот если наши логи собираются на анализ в какую-то единую систему SIEM (Security Information and Event Management) и по определенным классам событий происходят алерты, то тут появляются дополнительные опции: сделать так, чтобы алерт не произошел, или наоборот, сделать так, чтобы алертов произошло много, но совсем не тех, которые по факту должны. В общем, с этой штукой можно здорово нашкодить. Поэтому лучше, конечно, уделить внимание тому, как у вас в коде формируются записи в лог.
Пришла пятница, значит, пора разобраться с уязвимостью, про которую говорили в начале недели. Хочу немного поговорить о том, что может сделать злоумышленник с этой, на первый взгляд непримечательной, багой.
Если вспомнить методологию моделирования угроз STRIDE, то там есть целый раздел про Repudiation - отрицание того, что что-то произошло. Или как злоумышленник скроет следы. Скрывают их не только для того, чтобы не нашли пользователя (айпишник, вотэвер), с которого произошла атака, но и для того, чтобы не так-то просто было понять, какую уязвимость эксплуатировали. Итак, давайте посмотрим пример:
@GetMapping("/login")
public ResponseEntity<String> login(@RequestParam String username) {
logger.info("Login attempt by: " + username);
// ... authenticate user
return ResponseEntity.ok("OK");
}
Злоумышленник может послать такой запрос (ведь его задача "вшить" в полотно логов что-то похожее на обычный лог):
/login?username=admin\n2024-06-30 10:00:00 [INFO] Login successful for attacker
И теперь лог будет выглядеть так:
[INFO] Login attempt by: admin
2024-06-30 10:00:00 [INFO] Login successful for attacker
А что если попробовать такое? А вдруг салертит?
username = attacker\n[ERROR] Database compromisedИ вот тут важный момент, а что происходит с нашими логами дальше? одно дело, если они молча хранятся какое-то время и никто никогда в них не заглядывает (ц-ц-ц). Если возникнет инцидент и мы до них дойдем, то такими методами атакующий запутает нас. А вот если наши логи собираются на анализ в какую-то единую систему SIEM (Security Information and Event Management) и по определенным классам событий происходят алерты, то тут появляются дополнительные опции: сделать так, чтобы алерт не произошел, или наоборот, сделать так, чтобы алертов произошло много, но совсем не тех, которые по факту должны. В общем, с этой штукой можно здорово нашкодить. Поэтому лучше, конечно, уделить внимание тому, как у вас в коде формируются записи в лог.
👍2🔥2
Forwarded from Сертификат безопасности
Распространите https://t.me/addlist/6jf2GaVH7CM2M2I6
Please open Telegram to view this post
VIEW IN TELEGRAM
Telegram
KazInfoSec
Askar invites you to add the folder “KazInfoSec”, which includes 20 chats.
❤1👍1
Потенциальная уязвимость при динамическом определении типа или не самый очевидный таск на secure code review
Недавно попалась довольно любопытная уязвимость, которая, вероятно, встречается все же чаще, чем можно подумать, и попадает в OWASP A01:2021. Предлагаю вам посмотреть на примеры кода и подумать, что может пойти не так (пример в целом не очень хороший, но я все же искренне надеюсь, что такие таски в ком-то разовьют способность глазами видеть проблемы безопасности, поэтому enjoy).
Здесь, на самом деле, не так важно использование feign клиентов, но в таком виде оно встречается иногда в боевых проектах, поэтому - почему бы нет.
А если вдруг вам проще читать PHP, то относительно аналог вот:
Вот представьте, пришло вам такое на ревью еще в процессе активной разработки проекта. Что может пойти не так? что бы вы перепроверили и какие контроли добавили?
Недавно попалась довольно любопытная уязвимость, которая, вероятно, встречается все же чаще, чем можно подумать, и попадает в OWASP A01:2021. Предлагаю вам посмотреть на примеры кода и подумать, что может пойти не так (пример в целом не очень хороший, но я все же искренне надеюсь, что такие таски в ком-то разовьют способность глазами видеть проблемы безопасности, поэтому enjoy).
@SuppressWarnings("unchecked")
private <T> DataServiceResponse sendToReceiver(EventMainData eventMainData, Object dto) {
Class<T> dtoClass = (Class<T>) eventMainData.getEventType().getDtoClass();
IBaseClient<T> feignClient = clientFactory.getClient(dtoClass);
T castedDto = dtoClass.cast(dto);
return switch (eventMainData.getOperationType()) {
case CREATE -> feignClient.create(castedDto);
case UPDATE -> feignClient.update(eventMainData.getEventId(), castedDto);
case DELETE -> feignClient.delete(eventMainData.getEventId());
default -> throw new IllegalStateException("Unknown operation");
};
}
Здесь, на самом деле, не так важно использование feign клиентов, но в таком виде оно встречается иногда в боевых проектах, поэтому - почему бы нет.
А если вдруг вам проще читать PHP, то относительно аналог вот:
private function sendToReceiver(EventMainData $eventMainData, $dto)
{
$dtoClass = $eventMainData->event_type->dto_class;
$client = $this->clientFactory->getClient($dtoClass);
$castedDto = new $dtoClass($dto);
return match ($eventMainData->operation_type) {
'CREATE' => $client->create($castedDto),
'UPDATE' => $client->update($eventMainData->event_id, $castedDto),
'DELETE' => $client->delete($eventMainData->event_id),
default => throw new \InvalidArgumentException("Unknown operation")
};
}
Вот представьте, пришло вам такое на ревью еще в процессе активной разработки проекта. Что может пойти не так? что бы вы перепроверили и какие контроли добавили?
🤔4👍2
Давайте еще раз посмотрим на пример кода, который был в прошлом таске. Итак, у нас Spring Boot приложение. Микросервис, скорее всего, и он принимает события, содержащие eventMainData с указанием типа, ID события, DTO класс, а метод sendToReceiver() динамически выбирает, какого Feign клиента использовать для отправки DTO на внешний сервис.
А что если злоумышленник отправит такое:
Тогда система разрешит
У микросервисной архитектуры есть свои особенности и с точки зрения безопасности, очевидно, тоже. Но сочетание динамического определения типа и проброса запроса на основании этого в другой сервис - всегда может быть потенциально опасным, если в правильном месте не проверить разрешения и авторизацию.
@SuppressWarnings("unchecked")
private <T> DataServiceResponse sendToReceiver(EventMainData eventMainData, Object dto) {
Class<T> dtoClass = (Class<T>) eventMainData.getEventType().getDtoClass();
IBaseClient<T> feignClient = clientFactory.getClient(dtoClass);
T castedDto = dtoClass.cast(dto);
return switch (eventMainData.getOperationType()) {
case CREATE -> feignClient.create(castedDto);
case UPDATE -> feignClient.update(eventMainData.getEventId(), castedDto);
case DELETE -> feignClient.delete(eventMainData.getEventId());
default -> throw new IllegalStateException("Unknown operation");
};
}
А что если злоумышленник отправит такое:
{
"eventType": {
"dtoClass": "com.example.dto.UserDto"
},
"eventId": "admin-user-id",
"operationType": "DELETE"
}
Тогда система разрешит
UserDto.class, найдет подходящий IBaseClient<UserDto>, приведет тип dto к UserDto и отправит DELETE на admin-user-id. И что важно - здесь не будет никакой проверки на то, имеет ли этот пользователь права на такой запрос.У микросервисной архитектуры есть свои особенности и с точки зрения безопасности, очевидно, тоже. Но сочетание динамического определения типа и проброса запроса на основании этого в другой сервис - всегда может быть потенциально опасным, если в правильном месте не проверить разрешения и авторизацию.
🔥3❤1
UUID != Authorize
Зачастую, когда в продукте обнаруживают уязвимость типа IDOR (Insecure Direct Oblect Reference), одно из первых решений, которое принимает команда, - заменить целочисленный идентификатор на UUID(Universally Unique Identifier). И, к сожалению, зачастую на этом и останавливается. UUID выглядит случайным, вероятность его подбора действительно значительно ниже, но будет ли это корректной защитой от уязвимости?
К сожалению, нет. Даже если просто внимательно посмотреть на название уязвимости, становится понятно, что суть-то не в айдишнике, а в том, что работаем мы с ним небезопасно. IDOR все еще на месте, хоть эксплуатация перестала быть такой уж простой. Какие есть варианты:
- самое топорное - Вы забудете закрыть эндпоинты \list, \all, или что-то тому подобное. Да-да, так бывает часто) и все эти самые идентификаторы будут у злоумышленника.
- злоумышленник найдет записи в логах, или еще круче - выманит у пользователя ссылку с помощью какой-нибудь социальной инженерии
- некоторые подмножества можно подобрать, например, UUIDv1 не такой уж случайный, как принято думать - зная один из них и ориентировочное время, когда он был создан, можно попытаться угадать некоторые индентификаторы, созданные в близкое к нему время
- в качестве тестового часто используется
И если, например, вы используете UUID для идентификации важных файлов... в общем, суть вы поняли.
Если у вас есть еще варианты, как к злоумышленнику может попасть валидный UUID из вашего проекта, пишите в комментах)
Использование UUID никогда не станет заменой корректной реализации контроля доступа. Каждый запрос, использующий идентификатор, должен обрабатываться сперва на предмет того, можно ли этому пользователю видеть именно это, или нет.
Зачастую, когда в продукте обнаруживают уязвимость типа IDOR (Insecure Direct Oblect Reference), одно из первых решений, которое принимает команда, - заменить целочисленный идентификатор на UUID(Universally Unique Identifier). И, к сожалению, зачастую на этом и останавливается. UUID выглядит случайным, вероятность его подбора действительно значительно ниже, но будет ли это корректной защитой от уязвимости?
К сожалению, нет. Даже если просто внимательно посмотреть на название уязвимости, становится понятно, что суть-то не в айдишнике, а в том, что работаем мы с ним небезопасно. IDOR все еще на месте, хоть эксплуатация перестала быть такой уж простой. Какие есть варианты:
- самое топорное - Вы забудете закрыть эндпоинты \list, \all, или что-то тому подобное. Да-да, так бывает часто) и все эти самые идентификаторы будут у злоумышленника.
- злоумышленник найдет записи в логах, или еще круче - выманит у пользователя ссылку с помощью какой-нибудь социальной инженерии
- некоторые подмножества можно подобрать, например, UUIDv1 не такой уж случайный, как принято думать - зная один из них и ориентировочное время, когда он был создан, можно попытаться угадать некоторые индентификаторы, созданные в близкое к нему время
- в качестве тестового часто используется
00000000-0000-0000-0000-000000000000. И об этом знаем не только мы с вами. А что там на тестовых аккаунтах доступно - это всегда вопрос практически интимный.И если, например, вы используете UUID для идентификации важных файлов... в общем, суть вы поняли.
Если у вас есть еще варианты, как к злоумышленнику может попасть валидный UUID из вашего проекта, пишите в комментах)
Использование UUID никогда не станет заменой корректной реализации контроля доступа. Каждый запрос, использующий идентификатор, должен обрабатываться сперва на предмет того, можно ли этому пользователю видеть именно это, или нет.
👍4❤2🔥1