Примеры уязвимостей бизнес-логики

Уязвимости бизнес-логики относительно специфичны для контекста, в котором они возникают. Однако, несмотря на то что отдельные случаи логических изъянов сильно различаются, они могут иметь много общих тем. В частности, их можно условно сгруппировать на основе исходных ошибок, которые изначально привели к уязвимости.

В этом разделе мы рассмотрим примеры типичных ошибок, которые допускают команды проектирования и разработки, и покажем, как они напрямую приводят к изъянам бизнес-логики. Независимо от того, разрабатываете ли вы свои приложения или проводите аудит существующих, вы можете извлечь уроки из этих примеров и применить то же критическое мышление к другим приложениям, с которыми столкнётесь.

Мы рассмотрим следующие примеры:

Чрезмерное доверие к средствам контроля на стороне клиента

Фундаментально ошибочное предположение — что пользователи будут взаимодействовать с приложением только через предоставленный веб-интерфейс. Это особенно опасно, поскольку приводит к дальнейшему предположению, что клиентская валидация предотвратит передачу пользователями вредоносного ввода. Однако злоумышленник может просто использовать такие инструменты, как Burp Proxy, чтобы подменять данные после того, как они были отправлены браузером, но до того, как они будут переданы в серверную логику. Это фактически делает клиентские средства контроля бесполезными.

Принятие данных на веру без проведения надлежащих проверок целостности и серверной валидации может позволить злоумышленнику нанести всевозможный ущерб при относительно небольших усилиях. Точно чего он сможет добиться, зависит от функциональности и от того, что она делает с контролируемыми данными. В правильном контексте такой изъян может иметь разрушительные последствия как для бизнес-функционала, так и для безопасности самого сайта.

Отсутствие обработки нетипичного ввода

Одна из задач логики приложения — ограничить пользовательский ввод значениями, соответствующими бизнес-правилам. Например, приложение может быть спроектировано для принятия произвольных значений определённого типа данных, но логика определяет, допустимо ли это значение с точки зрения бизнеса. Многие приложения включают числовые лимиты в свою логику. Это могут быть лимиты, предназначенные для управления запасами, применения бюджетных ограничений, запуска этапов цепочки поставок и т.п.

Возьмём простой пример интернет-магазина. При заказе товаров пользователи обычно указывают желаемое количество. Хотя теоретически любой целочисленный ввод является валидным, бизнес-логика может предотвращать заказ большего количества единиц, чем есть в наличии, например.

Чтобы внедрить такие правила, разработчикам нужно предусмотреть все возможные сценарии и встроить способы их обработки в логику приложения. Иными словами, им нужно «сказать» приложению, следует ли разрешать конкретный ввод и как оно должно реагировать при различных условиях. Если нет явной логики для обработки конкретного случая, это может привести к неожиданному и потенциально эксплуатируемому поведению.

Например, числовой тип данных может принимать отрицательные значения. В зависимости от связанной функциональности для бизнес-логики может не иметь смысла это разрешать. Однако если приложение не выполняет адекватную серверную валидацию и не отклоняет такой ввод, злоумышленник может передать отрицательное значение и вызвать нежелательное поведение.

Рассмотрим перевод средств между двумя банковскими счетами. Эта функциональность почти наверняка проверяет, достаточно ли средств у отправителя перед выполнением перевода:

Но если логика недостаточно предотвращает передачу пользователями отрицательного значения в параметре amount, это может быть использовано злоумышленником для обхода проверки баланса и перевода средств в «неправильном» направлении. Если злоумышленник отправит -$1000 на счёт жертвы, это может привести к тому, что он получит $1000 от жертвы. Логика всегда оценит, что -1000 меньше текущего баланса, и одобрит перевод.

Простые логические изъяны вроде этого могут быть разрушительными, если они встречаются в «правильной» функциональности. Их также легко пропустить на этапах разработки и тестирования, тем более что такой ввод может блокироваться клиентскими средствами контроля веб-интерфейса.

При аудите приложения следует использовать такие инструменты, как Burp Proxy и Repeater, чтобы пытаться отправлять нетипичные значения. В частности, пробуйте ввод в диапазонах, которые легитимные пользователи вряд ли когда-либо введут. К ним относятся исключительные по величине (очень большие/очень маленькие) числовые значения и аномально длинные строки для текстовых полей. Можно даже попробовать неожиданные типы данных. Наблюдая за ответом приложения, попытайтесь ответить на следующие вопросы:

  • Накладываются ли какие-либо ограничения на данные?

  • Что происходит, когда вы достигаете этих ограничений?

  • Выполняется ли какая-либо трансформация или нормализация вашего ввода?

Это может выявить слабую валидацию, которая позволяет манипулировать приложением необычными способами. Помните, что если вы нашли на целевом сайте одну форму, которая небезопасно обрабатывает нетипичный ввод, скорее всего, другие формы имеют те же проблемы.

Ошибочные предположения о поведении пользователей

Одна из наиболее распространённых причин логических уязвимостей — ошибочные предположения о поведении пользователей. Это может привести к целому ряду проблем, когда разработчики не учли потенциально опасные сценарии, нарушающие эти предположения. В этом разделе мы приведём предостерегающие примеры распространённых предположений, которых следует избегать, и покажем, как они приводят к опасным логическим изъянам.

Доверенные пользователи не всегда останутся доверенными

Приложения могут казаться безопасными, потому что они реализуют, на первый взгляд, надёжные меры для обеспечения соблюдения бизнес-правил. К сожалению, некоторые приложения допускают ошибку, предполагая, что раз пользователь изначально прошёл эти строгие проверки, то ему и его данным можно доверять бесконечно. Это может привести к относительно слабому применению тех же мер контроля в дальнейшем.

Если бизнес-правила и меры безопасности применяются непоследовательно по всему приложению, это может привести к потенциально опасным лазейкам, которые злоумышленник может эксплуатировать.

Пользователи не всегда будут предоставлять обязательный ввод

Одно заблуждение заключается в том, что пользователи всегда будут заполнять обязательные поля ввода. Браузеры могут препятствовать отправке формы без обязательного ввода обычными пользователями, но, как мы знаем, злоумышленники могут подменять параметры «в пути». Это включает даже полное удаление параметров.

Это особенно проблематично в случаях, когда несколько функций реализованы в одном и том же серверном скрипте. В таком случае наличие или отсутствие конкретного параметра может определять, какой код будет выполнен. Удаление значений параметров может позволить атакующему получить доступ к путям кода, которые должны быть недоступны.

При поиске логических изъянов следует пробовать удалять каждый параметр по очереди и наблюдать, как это влияет на ответ. Убедитесь, что вы:

  • Удаляете только один параметр за раз, чтобы гарантировать достижение всех релевантных путей кода.

  • Пробуете удалять как имя параметра, так и значение. Сервер обычно обрабатывает оба случая по-разному.

  • Проходите многошаговые процессы до завершения. Иногда вмешательство в параметр на одном шаге влияет на другой шаг дальше по потоку.

Это относится как к параметрам URL и POST, так и к кукам — не забудьте их проверить. Этот простой процесс может выявить странное поведение приложения, которое может быть эксплуатируемым.

Пользователи не всегда будут следовать задуманной последовательности

Многие транзакции опираются на предопределённые рабочие процессы, состоящие из последовательности шагов. Веб-интерфейс обычно проводит пользователей через этот процесс, переводя их на следующий шаг каждый раз, когда текущий завершён. Однако атакующие не обязательно будут придерживаться этой задуманной последовательности. Непринятие этого во внимание может привести к опасным изъянам, которые относительно просто эксплуатировать.

Например, многие сайты, реализующие двухфакторную аутентификацию, требуют, чтобы пользователи сначала входили на одной странице, а затем вводили проверочный код на отдельной странице. Предположение, что пользователи всегда будут следовать этому процессу до конца, и отсутствие проверки того, что они это делают, может позволить злоумышленникам полностью обойти шаг 2FA.

Предположения о последовательности событий могут приводить к множеству проблем даже в рамках одного и того же процесса или функциональности. Используя такие инструменты, как Burp Proxy и Repeater, увидев один запрос, злоумышленник может воспроизводить его сколько угодно и использовать принудительный обход (forced browsing), чтобы выполнять любые взаимодействия с сервером в любом порядке. Это позволяет ему выполнять различные действия, пока приложение находится в неожиданном состоянии.

Чтобы выявить такие изъяны, следует использовать принудительный обход, отправляя запросы в непредусмотренной последовательности. Например, можно пропускать отдельные шаги, обращаться к одному шагу более одного раза, возвращаться к ранним шагам и т. п. Обратите внимание на то, как доступны разные шаги. Хотя часто вы просто отправляете GET- или POST-запрос на конкретный URL, иногда вы можете попасть на шаг, отправив разные наборы параметров на один и тот же URL. Как и при любых логических изъянах, попытайтесь определить, какие предположения сделали разработчики и где находится поверхность атаки. Затем ищите способы нарушить эти предположения.

Учтите, что такое тестирование часто приведёт к исключениям, поскольку ожидаемые переменные имеют значения null или не инициализированы. Попадание в место в частично определённом или несогласованном состоянии также, скорее всего, вызовет ошибки приложения. В этом случае обращайте особое внимание на любые сообщения об ошибках или отладочную информацию, с которой вы сталкиваетесь. Они могут быть ценным источником раскрытия информации и помогут вам тонко настроить атаку и понять ключевые детали поведения бэкенда.

Изъяны, специфичные для предметной области

Во многих случаях вы столкнётесь с логическими изъянами, специфичными для предметной области или назначения сайта.

Функциональность скидок в интернет-магазинах — классическая поверхность атаки при поиске логических изъянов. Это может быть потенциальной «золотой жилой» для атакующего, с массой базовых логических изъянов в том, как применяются скидки.

Например, рассмотрим интернет-магазин, предлагающий скидку 10% на заказы свыше $1000. Это может быть уязвимо для злоупотреблений, если бизнес-логика не проверяет, был ли заказ изменён после применения скидки. В этом случае злоумышленник может просто добавить товары в корзину, пока не достигнет порога в $1000, затем удалить ненужные товары перед оформлением заказа. В результате он получит скидку на заказ, хотя он больше не удовлетворяет задуманным критериям.

Особое внимание стоит уделять любым ситуациям, где цены или другие чувствительные значения корректируются на основе критериев, определяемых действиями пользователя. Постарайтесь понять, какие алгоритмы использует приложение для этих корректировок и на каком этапе они выполняются. Часто это включает манипулирование приложением так, чтобы оно находилось в состоянии, когда применённые корректировки не соответствуют исходным критериям, задуманным разработчиками.

Чтобы выявить такие уязвимости, нужно тщательно продумать, каких целей может добиваться злоумышленник, и попытаться найти разные способы их достижения с использованием предоставленной функциональности. Для этого может потребоваться определённый уровень знаний предметной области, чтобы понять, что может быть выгодно в данном контексте. Для простоты, примеры в этой теме относятся к домену, знакомому всем пользователям — интернет-магазину. Однако, независимо от того, занимаетесь ли вы багбаунти, пентестом или просто являетесь разработчиком, который старается писать более безопасный код, вы можете встретить приложения из менее знакомых доменов. В таком случае следует читать как можно больше документации и, где возможно, общаться с предметными экспертами из этой отрасли, чтобы понять их видение. Это может звучать трудоёмко, но чем более «узкой» является область, тем вероятнее, что другие тестировщики пропустили множество багов.

Предоставление «оракула шифрования» (encryption oracle)

Опасные сценарии возникают, когда управляемый пользователем ввод шифруется, а получившийся шифротекст затем каким-то образом возвращается пользователю. Такой ввод иногда называют «оракулом шифрования». Злоумышленник может использовать этот ввод, чтобы шифровать произвольные данные с использованием корректного алгоритма и асимметричного ключа.

Это становится опасным, когда в приложении есть другие управляемые пользователем вводы, ожидающие данные, зашифрованные тем же алгоритмом. В этом случае злоумышленник потенциально может использовать оракул шифрования для генерации валидного зашифрованного ввода, а затем передать его в другие чувствительные функции.

Проблема может усугубляться, если на сайте есть другой управляемый пользователем ввод, предоставляющий обратную функцию. Это позволит злоумышленнику расшифровать другие данные, чтобы понять ожидаемую структуру. Это экономит часть работы по созданию вредоносных данных, но не обязательно требуется для успешной эксплуатации.

Критичность наличия оракула шифрования зависит от того, какая функциональность также использует тот же алгоритм, что и оракул.

Несоответствия парсера адресов электронной почты

Некоторые сайты парсят адреса электронной почты, чтобы извлечь домен и определить, к какой организации принадлежит владелец адреса. Хотя этот процесс может поначалу показаться простым, на самом деле он очень сложен, даже для валидных адресов, соответствующих RFC.

Несоответствия в том, как парсятся адреса электронной почты, подрывают эту логику. Эти несоответствия возникают, когда разные части приложения по-разному обрабатывают email-адреса.

Злоумышленник может эксплуатировать эти несоответствия с помощью техник кодирования, чтобы скрывать части адреса электронной почты. Это позволяет создавать email-адреса, которые проходят начальные проверки валидации, но интерпретируются иначе парсинг-логикой на сервере.

Основное влияние несоответствий парсера адресов электронной почты — несанкционированный доступ. Злоумышленники могут регистрировать учётные записи, используя на вид валидные адреса из ограниченных доменов. Это позволяет им получать доступ к чувствительным областям приложения, таким как панели администрирования или функции, доступные только ограниченным пользователям.

Больше информации

Для подробной информации о несоответствиях при разборе email-адресов, включая способы их эксплуатации, см. whitepaper Splitting the Email Atom: Exploiting Parsers to Bypass Access Controls Гарета Хэйеса из команды PortSwigger Research.

Last updated