Ошибка в бизнес логике приложения

Время на прочтение
9 мин

Количество просмотров 3.4K

М/Ф "В стране невыученных уроков"
М/Ф «В стране невыученных уроков»

Мы как-то писали про SSRF-атаку, которая входит в список наиболее распространенных уязвимостей OWASP Top 10. Однако мир уязвимостей намного разнообразнее и, конечно же, не ограничивается этим списком. Сегодня мы хотим рассказать про уязвимости, связанные с бизнес-логикой. Что в них необычного? Это как доказать, что 2+2=5. Последовательность действий кажется правильной, все операции разрешенными, а результат совсем не тот, который закладывался при разработке. Но мы же знаем, что в доказательстве есть ошибки! Рассмотрим, как подобные задачки решаются при анализе защищенности и какие неожиданные результаты можно получить, используя обычную функциональность приложений.

Бизнес-логика и какие уязвимости в ней могут быть

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

Вот простой пример. Для защиты от атак подбора пароля в приложении реализован механизм CAPTCHA. При работе через веб-интерфейс после трех неудачных попыток ввода требуется решить типичную задачу с картинками. Однако при прямой отправке запросов на сервер никаких ограничений не предусмотрено. То есть фактически CAPTCHA никак не защищает от атак подбора. Как так получилось, нам остается только догадываться. Возможно, разработчики решили, что никто не будет напрямую обращаются к API. А зря!

Уязвимости бизнес-логики отличаются от большинства других уязвимостей:

  • они разнообразны, можно сказать, уникальны для каждого приложения. Это связано с особенностями работы и направленностью каждого отдельного приложения;

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

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

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

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

Теперь, понимая, что это за уязвимости бизнес-логики и в чем их особенности, перейдем к обещанным «задачкам».

Не простой перебор идентификаторов

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

Посмотрим на запросы, которые отправляются на сервер при обычной работе приложения:

Запрос для получения информации о пользователе

Запрос для получения информации о пользователе

Обратим внимание на параметр id и поле password, которое содержит пароль пользователя(!). Пробуем заменить идентификатор на любое другое число – в ответе получаем данные другого пользователя. Осталось дело за малым, автоматизируем перебор идентификаторов и собираем список пользователей и их паролей.

Представленный пример содержит сразу две уязвимости:

  • небезопасное управление паролями – их хранение в открытом виде и передача пользователям;

  • небезопасные прямые ссылки на объекты – обращение к объектам на основе полученного от пользователя идентификатора.

Управление паролями – это отдельная тема, которой мы не будем касаться в рамках текущей статьи. А вот на небезопасных прямых ссылках на объекты остановимся подробно. Безусловно, подобные уязвимости также относятся к недостаткам контроля доступа (OWASP Top 10, A01:2021 – Broken Access Control) и могут быть расценены как пропущенные проверки прав. Однако посмотрим на проблему именно со стороны бизнес-логики.

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

Сценарий работы приложения при обращении неаутентифицированного пользователя

Сценарий работы приложения при обращении неаутентифицированного пользователя
Сценарий работы приложения при обращении пользователя с активной сессией
Сценарий работы приложения при обращении пользователя с активной сессией

И вот уже появляется ошибка. При запросе данных (/api/person?id=22) не проверяются ни сессия, ни права пользователя. Поэтому представленный в начале запрос на получение паролей успешно реализуется. При этом изначальные требования о том, что неаутентифицированный пользователь не может просмотреть страницу профиля – выполняется.

Как так получилось? При проработке сценариев использования не было учтено возможное прямое обращение к API. Конечно, обычно мы работаем с приложением через браузер и взаимодействуем с визуальными элементами, и одной проверки сессии в этом случае достаточно. И это одна из самых распространенных ошибок бизнес-логики – неверные предположение о действиях пользователей. Чтобы ее исключить, необходимо проверять права при каждом обращении к API. А это, согласитесь, уже не самая простая задача.

Неучтенный сценарий прямого обращения к API

Неучтенный сценарий прямого обращения к API

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

Как мы уже говорили выше, такие ошибки сложно обнаружить автоматизированными сканерами. Правда, технологии не стоят на месте, и сканеры уже умеют обнаруживать подобные уязвимости, хоть и с большим уровнем ошибок первого и второго рода. Поэтому пока лучший способ обнаружить небезопасные прямые ссылки на объекты – ручной анализ. При этом стоит помнить, что идентификаторы – это не только инкрементальные числа. Название файлов, методов, уникальные идентификаторы (GUID) – небезопасные прямые ссылки на объекты могут быть везде. Поэтому необходимо анализировать всю функциональность приложения и проверять полученные результаты по установленной матрице доступа.

Доверяй, но проверяй

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

Возможно, многие знают хрестоматийный пример изменения цены товара в запросе. Это демонстрация подделки параметров (Parameter Tampering) – достаточно простой атаки, которая также направлена на бизнес-логику приложений. Основная ее идея в том, что разработчики используют скрытые поля на странице или другие зафиксированные параметры как данные из достоверных источников. Стоит отметить, что это могут быть также cookie-файлы, значения заголовков и т.д. То есть все, что может быть изменено при отправке запроса.

Атака Parameter Tampering: изменение параметра price в запросе

Атака Parameter Tampering: изменение параметра price в запросе

Но подмена параметров возможна и в ответах сервера. Это кажется уже не таким очевидным и поэтому становится причиной различных ошибок логики. Достаточно распространенный случай – реализация всевозможных проверок на стороне клиента: прав, баланса, роли и т.д.

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

Запрос информации о пользователе: недостаточное количество бонусов для покупок

Запрос информации о пользователе: недостаточное количество бонусов для покупок

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

Правило в Burp Suite для автоматической замены значения параметра в ответе

Правило в Burp Suite для автоматической замены значения параметра в ответе
Запрос информации о пользователе: изменение количества бонусов для покупок
Запрос информации о пользователе: изменение количества бонусов для покупок

Как и можно было предположить, на экране отображается введенное нами значение бонусов, а товары в каталоге теперь доступны для добавления в корзину. Попытаемся оформить заказ – все проходит успешно. В итоге получается, что товар приобретен даже при недостаточном количестве бонусов.

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

Описанный выше сценарий покупки товаров за бонусы

Описанный выше сценарий покупки товаров за бонусы

Некорректные проверки прав также часто встречаются в одностраничных приложениях (Single Page Application, SPA), в которых в зависимости от уровня привилегий отображается тот или иной интерфейс. В совокупности с ранее описанной уязвимостью (небезопасные прямые ссылки на объекты) это представляет значительную опасность для всего приложения.

Параметр, которому точно нельзя доверять

Параметр, которому точно нельзя доверять

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

Вот так просто раскрываются токены, ключи и учетные данные в js-сценариях

Вот так просто раскрываются токены, ключи и учетные данные в js-сценариях

Вокруг да около

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

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

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

1 солярик

=>

100 рублей

1 минисолярик

=>

0.01 солярика или 1 рубль

Итак, попробуем купить 1 солярик меньше, чем за 100 рублей.

Проведенная схема – это пример атаки на округление. Действительно, 40 копеек – это 0.004 солярика, что по обычным правилам округления меньше 0.01 солярика, то есть минимальной единицы. А вот 57 копеек – 0.0057 солярика и по обычным правилам округления получаем 0.01 солярика или 1 минисолярик. Подобная атака известна далеко не первый год, и ей все еще подвергаются банковские приложения.

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

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

Работа с числами с плавающей точкой полна сюрпризов

Работа с числами с плавающей точкой полна сюрпризов

Нет в наличии

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

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

Значение параметра stock_level при запросе информации о товаре

Значение параметра stock_level при запросе информации о товаре
Значение параметра stock_level после добавления товара в корзину
Значение параметра stock_level после добавления товара в корзину

Видите разницу в единицу? Попробуем добавить в корзину максимальное количество товара, доступное на складе, и посмотрим, что изменится в каталоге.

Добавление максимального количества товара в корзину

Добавление максимального количества товара в корзину

Тем временем добавленный в корзину товар стал недоступен для оформления и покупки.

Отсутствие добавленного в корзину товара

Отсутствие добавленного в корзину товара

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

Казнить, нельзя помиловать

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

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

Автор: Ольга Рыбакова, аналитик отдела анализа защищенности Solar JSOC

Business Logic Errors

Introduction

Business Logic Errors are ways of using the legitimate processing flow of an application in a way that results in a negative consequence to the organization.

Where to find

This vulnerability can appear in all features of the application.

How to exploit

  1. Review Functionality

    • Some applications have an option where verified reviews are marked with some tick or it’s mentioned. Try to see if you can post a review as a Verified Reviewer without purchasing that product.
    • Some app provides you with an option to provide a rating on a scale of 1 to 5, try to go beyond/below the scale-like provide 0 or 6 or -ve.
    • Try to see if the same user can post multiple ratings for a product. This is an interesting endpoint to check for Race Conditions.
    • Try to see if the file upload field is allowing any exts, it’s often observed that the devs miss out on implementing protections on such endpoints.
    • Try to post reviews like some other users.
    • Try performing CSRF on this functionality, often is not protected by tokens
  2. Coupon Code Functionality

    • Apply the same code more than once to see if the coupon code is reusable.
    • If the coupon code is uniquely usable, try testing for Race Condition on this function by using the same code for two accounts at a parallel time.
    • Try Mass Assignment or HTTP Parameter Pollution to see if you can add multiple coupon codes while the application only accepts one code from the Client Side.
    • Try performing attacks that are caused by missing input sanitization such as XSS, SQLi, etc. on this field
    • Try adding discount codes on the products which are not covered under discounted items by tampering with the request on the server-side.
  3. Delivery Charges Abuse

    • Try tampering with the delivery charge rates to -ve values to see if the final amount can be reduced.
    • Try checking for the free delivery by tampering with the params.
  4. Currency Arbitrage

    • Pay in 1 currency say USD and try to get a refund in EUR. Due to the diff in conversion rates, it might be possible to gain more amount.
  5. Premium Feature Abuse

    • Try forcefully browsing the areas or some particular endpoints which come under premium accounts.
    • Pay for a premium feature and cancel your subscription. If you get a refund but the feature is still usable, it’s a monetary impact issue.
    • Some applications use true-false request/response values to validate if a user is having access to premium features or not.
    • Try using Burp’s Match & Replace to see if you can replace these values whenever you browse the app & access the premium features.
    • Always check cookies or local storage to see if any variable is checking if the user should have access to premium features or not.
  6. Refund Feature Abuse

    • Purchase a product (usually some subscription) and ask for a refund to see if the feature is still accessible.
    • Try for currency arbitrage explained yesterday.
    • Try making multiple requests for subscription cancellation (race conditions) to see if you can get multiple refunds.
  7. Cart/Wishlist Abuse

    • Add a product in negative quantity with other products in positive quantity to balance the amount.
    • Add a product in more than the available quantity.
    • Try to see when you add a product to your wishlist and move it to a cart if it is possible to move it to some other user’s cart or delete it from there.
  8. Thread Comment Functionality

    • Unlimited Comments on a thread
    • Suppose a user can comment only once, try race conditions here to see if multiple comments are possible.
    • Suppose there is an option: comment by the verified user (or some privileged user) try to tamper with various parameters in order to see if you can do this activity.
    • Try posting comments impersonating some other users.
  9. Parameter Tampering

    • Tamper Payment or Critical Fields to manipulate their values
    • Add multiple fields or unexpected fields by abusing HTTP Parameter Pollution & Mass Assignment
    • Response Manipulation to bypass certain restrictions such as 2FA Bypass

References

  • @harshbothra_

Business Logic Errors

Introduction

Business Logic Errors are ways of using the legitimate processing flow of an application in a way that results in a negative consequence to the organization.

Where to find

This vulnerability can appear in all features of the application.

How to exploit

  1. Review Functionality

    • Some applications have an option where verified reviews are marked with some tick or it’s mentioned. Try to see if you can post a review as a Verified Reviewer without purchasing that product.
    • Some app provides you with an option to provide a rating on a scale of 1 to 5, try to go beyond/below the scale-like provide 0 or 6 or -ve.
    • Try to see if the same user can post multiple ratings for a product. This is an interesting endpoint to check for Race Conditions.
    • Try to see if the file upload field is allowing any exts, it’s often observed that the devs miss out on implementing protections on such endpoints.
    • Try to post reviews like some other users.
    • Try performing CSRF on this functionality, often is not protected by tokens
  2. Coupon Code Functionality

    • Apply the same code more than once to see if the coupon code is reusable.
    • If the coupon code is uniquely usable, try testing for Race Condition on this function by using the same code for two accounts at a parallel time.
    • Try Mass Assignment or HTTP Parameter Pollution to see if you can add multiple coupon codes while the application only accepts one code from the Client Side.
    • Try performing attacks that are caused by missing input sanitization such as XSS, SQLi, etc. on this field
    • Try adding discount codes on the products which are not covered under discounted items by tampering with the request on the server-side.
  3. Delivery Charges Abuse

    • Try tampering with the delivery charge rates to -ve values to see if the final amount can be reduced.
    • Try checking for the free delivery by tampering with the params.
  4. Currency Arbitrage

    • Pay in 1 currency say USD and try to get a refund in EUR. Due to the diff in conversion rates, it might be possible to gain more amount.
  5. Premium Feature Abuse

    • Try forcefully browsing the areas or some particular endpoints which come under premium accounts.
    • Pay for a premium feature and cancel your subscription. If you get a refund but the feature is still usable, it’s a monetary impact issue.
    • Some applications use true-false request/response values to validate if a user is having access to premium features or not.
    • Try using Burp’s Match & Replace to see if you can replace these values whenever you browse the app & access the premium features.
    • Always check cookies or local storage to see if any variable is checking if the user should have access to premium features or not.
  6. Refund Feature Abuse

    • Purchase a product (usually some subscription) and ask for a refund to see if the feature is still accessible.
    • Try for currency arbitrage explained yesterday.
    • Try making multiple requests for subscription cancellation (race conditions) to see if you can get multiple refunds.
  7. Cart/Wishlist Abuse

    • Add a product in negative quantity with other products in positive quantity to balance the amount.
    • Add a product in more than the available quantity.
    • Try to see when you add a product to your wishlist and move it to a cart if it is possible to move it to some other user’s cart or delete it from there.
  8. Thread Comment Functionality

    • Unlimited Comments on a thread
    • Suppose a user can comment only once, try race conditions here to see if multiple comments are possible.
    • Suppose there is an option: comment by the verified user (or some privileged user) try to tamper with various parameters in order to see if you can do this activity.
    • Try posting comments impersonating some other users.
  9. Parameter Tampering

    • Tamper Payment or Critical Fields to manipulate their values
    • Add multiple fields or unexpected fields by abusing HTTP Parameter Pollution & Mass Assignment
    • Response Manipulation to bypass certain restrictions such as 2FA Bypass

References

  • @harshbothra_

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

Для начала рассмотрим каждый атрибут в отдельности.

Серьезность

Серьезность (Severity) — это атрибут, характеризующий влияние дефекта на работоспособность приложения. Проставляется специалистом по тестированию.

Серьезность имеет несколько параметров в зависимости от типа дефекта. Ее степень зависит от того, как она влияет на бизнес-логику (реализацию правил программы).

  • S1 – Блокирующая (Blocker). Блокирующая ошибка, приводящая приложение в нерабочее состояние, в результате которого дальнейшая работа с тестируемой системой или ее функциями становится невозможна.
  • S2 – Критическая (Critical). Критическая ошибка, неправильно работающая бизнес-логика, проблема, приводящая в нерабочее состояние некоторую часть системы, но есть возможность для работы с тестируемой функцией, используя другие входные точки.
  • S3 – Значительная (Major). Значительная ошибка, часть бизнес-логики работает некорректно. Ошибка не критична или есть возможность для работы с тестируемой функцией, используя другие входные точки.
  • S4 – Незначительная (Minor). Незначительная ошибка, не нарушающая бизнес-логику тестируемой части приложения, очевидная проблема пользовательского интерфейса.
  • S5 – Тривиальная (Trivial). Тривиальная ошибка, не касающаяся бизнес-логики приложения, плохо воспроизводимая проблема, малозаметная по средствам пользовательского интерфейса, проблема сторонних библиотек или сервисов, проблема, не оказывающая никакого влияния на общее качество продукта.

Из описания видно, что с помощью Серьезности мы указываем как найденная ошибка влияет на тестируемое приложение. Если из-за ошибки приложение полностью не работает, то Серьезность высокая. Если найденный дефект мало влияет на функционал и больше относится к визуальной части (например, опечатка в слове), то Серьезность низкая.

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

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

Сразу же отбрасываем Тривиальную и Незначительную Серьезность, так как из их описания понятно, что ошибка не должна сильно влиять на приложение.

У нас остается только три варианта: Значительная, Критическая и Блокирующая серьезности.

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

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

2. Невозможно указать адрес назначения с помощью “Указать на карте”.
Снова начинаем рассуждать. Тривиальная и Незначительная не подходят, потому что ошибка в какой-то мере нарушают бизнес логику работы приложения. Блокирующую можно не брать, т.к. функционал в целом работает и его можно использовать через другую точку входа, а именно ввести адрес вручную. Остается только два варианта: Критическая и Значительная. Мы уже сказали, что проблема не приводит к полной неработоспособности части функционала. Тем не менее это значительная ошибка, т.к. функционал частично не работает, следовательно остается только вариант Значительная. Его мы и укажем.

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

Приоритет

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

Приоритет (Priority) – это атрибут, указывающий на очередность выполнения задачи или устранения дефекта. Проставляется руководителем или менеджером проекта.

  • P1 – Высокий (High) – требуется исправить в первую очередь.
  • P2 – Средний (Medium) – требуется исправить во вторую очередь, когда нет дефектов с высоким приоритетом.
  • P3 – Низкий (Low) – исправляется в последнюю очередь, когда все дефекты с более высоким приоритетом уже исправлены.

С помощью приоритета менеджер проекта говорит, когда стоит исправить найденную проблему.

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

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

Приоритет определяется исходя из масштабности проблем для пользователей и продукта. Для понимая можно использовать матрицу:

Матрица определения приоритета

Матрица определения приоритета

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

Различия Серьезности и Приоритета

Различия Серьезности и Приоритета

________________________________
Если остались вопросы по определению параметров Серьезность и Приоритет, то задавайте их в комментариях к статье.
________________________________

Предыдущие статьи по оформлению баг-репорта:
Назначение отчета https://sedtest-school.ru/testovaya-dokumentacziya/otchety-o-defektah-naznachenie/
Шаблон отчета об ошибке https://sedtest-school.ru/testovaya-dokumentacziya/otchety-o-defektah-shablon-otcheta-ob-oshibke/

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

я просто устал от всего этого addErrors, получитьОшибки на каждом уровне и чувствую, что делаю что-то не так.

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

Заранее спасибо, если поделитесь мудростью и знаниями)

Небольшой фрагмент для иллюстрации проблемы:

class ErrorContainer {
    private $errors = array();
    function addError($error) { if (!is_array($error)) { $this->errors[] = $error;} else { $this->errors = array_merge($this->errors, $error); } }
    function getErrors() { return $this->errors[]; }
    function hasErrors() { return !empty($this->errors); }
}

class Processor extends ErrorContainer {
    function process($account_id, $orders) {
        $account = new Account();
        if (!$account->loadById($account_id)) { $this->addErrors($account->getErrors);}

        foreach ($orders as $order_id) {
            $order = new Order();
            if (!$order->loadById($order_id)) { $this->addErrors($order->getErrors);}
        }
    }

    return $this->hasErrors();
}

class Account extends ErrorContainer {
    function loadById($account_id) {
        $account = select_from_database($account_id);
        if (!$account) { $this->addError("Account is missing"); }
        if (!$account['active']) { $this->addError("Account is inactive"); }
        // and so on, some checks may add errors in a cycle

        return $this->hasErrors();
    }
}

class Order extends ErrorContainer {} // very similar to Account, but has its own checks

//Usage:

$errors = array();
$items = load_items_from_xml($xml);
foreach ($items as $item) {
    $processor = new Processor();
    if (!$processor->process($item['account_id'], $item['orders'])) {
        $errors = array_merge($errors, $processor->getErrors());
    }
}

You can decorate your Controller/Action with the [HandleErrorAttribute] to do just that.

For example:

    [HandleError]
    public ActionResult PlaceOrder(OrderDetails orderDetails)
    {
        orderService.PlaceOrder(orderDetails);
        return View("Success");
    }

You can set the appropriate View to load to depend on the Exception Type:

    [HandleError(ExceptionType=typeof(PlaceOrderException),View="OrdersError"]
    [HandleError(ExceptionType=typeof(Exception),View="GeneralError"]
    public ActionResult PlaceOrder(OrderDetails orderDetails)
    {
        orderService.PlaceOrder(orderDetails);
        return View("Success");
    }

Alternatively, you can register it globally on your global.asax:

    GlobalFilters.Filters.Add(new HandleErrorAttribute
    {
        View = "Error"
    }); 

P.S: The above example assumes your ‘Error/GeneralError/OrdersError’ Views are in the Shared folder. if they’re not, you’re gonna need to specify the full path.

Edit (as per your comment):

If you want to return Json instead of View, create the following ActionFilter:

public class HandleErrorJsonAttribute : FilterAttribute, IExceptionFilter
{
    public void OnException(ExceptionContext filterContext)
    {
        filterContext.ExceptionHandled = true;
        filterContext.HttpContext.Response.Clear();
        filterContext.HttpContext.Response.StatusCode = 500;
        filterContext.HttpContext.Response.TrySkipIisCustomErrors = true;

        filterContext.Result = new JsonResult
        {
            JsonRequestBehavior = JsonRequestBehavior.AllowGet,
            ContentType = "application/json",
            Data = new 
            {
                Msg = "An Error Occured",
                ExceptionMsg = filterContext.Exception.ToString()
            }
        };
    }
}

Then use the new [HandleErrorJson] attribute (as outlined above), or register it as a Global Filter in your global.asax.

Технические ошибки и ошибки бизнес-логики

Технические ошибки

Введение

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

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

Организационные и продуктовые задачи

Процесс создания проудкта, от постановки требований до исполнения в виде готового решения, состоит из двух частей:

  • Организационная
  • Техническая

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

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

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

В веб-приложениях это решается согласно двум принципам:

  • доставка информации об ошибках — это техническая задача, а отображение — клиентская;
  • способ доставки не имеет значения, сама ошибка должна быть информативной, чтобы можно было понять техническая или бизнесовая проблема.

Эти принципы реализуются следующими подходами:

  • Все ошибки проекта — это HTTP ошибки
  • Бизнес ошибки отдельно, технические ошибки отдельно

Подход «Все ошибки проекта — это HTTP ошикби»

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

  • Унификация — все ошибки обрабатываются единым образом
  • Упрощение отслеживания ошибок и их доставка до пользователя
  • Упрощения идентификации ошибок
  • Возможность дополнительной маршрутизации на основе кодов ошибок
  • Хорошо подходит для RESTFull сервисов

Обработка всего как технических ошибок

Основные коды HTTP ошибок

  • 1xx Status Codes [Informational]
  • 2xx Status Codes [Success]
  • 3xx Status Codes [Redirection]
  • 4xx Status Codes (Client Error)
  • 5xx Status Codes (Server Error)

Наиболее часто используются

200 OK
Indicates that the request has succeeded.
201 Created
Indicates that the request has succeeded and a new resource has been created as a result.

301 Moved Permanently
The URL of the requested resource has been changed permanently. The new URL is given by the Location header field in the response. This response is cacheable unless indicated otherwise.

304 Not Modified
Indicates the client that the response has not been modified, so the client can continue to use the same cached version of the response.

400 Bad Request
The request could not be understood by the server due to incorrect syntax. The client SHOULD NOT repeat the request without modifications.

401 Unauthorized
Indicates that the request requires user authentication information. The client MAY repeat the request with a suitable Authorization header field

403 Forbidden
Unauthorized request. The client does not have access rights to the content. Unlike 401, the client’s identity is known to the server.

404 Not Found
The server can not find the requested resource.

429 Too Many Requests
The user has sent too many requests in a given amount of time (“rate limiting”).

500 Internal Server Error
The server encountered an unexpected condition that prevented it from fulfilling the request.

503 Service Unavailable
The server is not ready to handle the request.

Недостатки HTTP ошибок

  • HTTP разрабатывался для гетерогенных сред распространения информации, может содержать огромное количество промежуточных узлов
  • HTTP ошибки могут логироваться и способствовать утечке бизнес-информации
  • HTTP и Бизнес — это разные уровни астракции — протечка асбтракции
  • Логика ничего не знает о транспорте, усложняется обработка при использовании нескольких транспортов
  • Сопровождение HTTP ошибок могут выполнять люди, которые не понимают сути бизнес ошибок
  • Повышается уровень ложных срабатываний для подразделений сопровождения
  • Бизнес ошибки требуют обработки в клиенте, не всегда можно сделать обобщение
  • Ошибка может не дойти до конечной точки (клиента)

Особенности создания RFC

  • RFC означает Request for Comments (рабочее предложение)
  • RFC может содержать как описание стандартов, так и лучшие практики, просто информацию или что-то еще
  • стандарты размещаются в Standards Track
  • в самом начале стандарты являются просто предложениями «Proposed Standard»
  • если стандарт становится достаточно зрелым (т.е. широко применяется на практике и не вызывает проблем), его помечают как «Internet Standard»
  • с момента как стандарт получает статус Internet Standard ему также присваивается номер STDXX, который содержит набор RFC, относящихся к этому стандарту.

Из интересного: у RFC есть стадия обсуждения, в рамках которой в документ могут быть внесены изменения, затем наступает стадия AUTH48 когда автору RFC дается 48 часов (на самом деле около недели) на то, чтобы он окончательно сформировал и осмыслил документ. После этого документ либо публикуется, либо автор может отказаться от его публикации. После публикации документ получает номер RFC и уже не может быть изменен (к нему могут быть только добавлены сообщения об ошибках — Erratas). Но если ошибок слишком много, то можно выпустить еще один RFC.

RFC7807

RFC7808 скриншот

Предполагается, что ошибки передаются HTTP кодами:

`HTTP/1.1 403 Forbidden
Content-Type: application/problem+json
Content-Language: en

{
«type»: «https://example.com/probs/out-of-credit»,
«title»: «You do not have enough credit.»,
«detail»: «Your current balance is 30, but that costs 50.»,
«instance»: «/account/12345/msgs/abc»,
«balance»: 30,
«accounts»: [«/account/12345»,
«/account/67890»]
}
`

Полезнгая информация содержится в BODY
`
HTTP/1.1 400 Bad Request
Content-Type: application/problem+json
Content-Language: en

{
«type»: «https://example.net/validation-error»,
«title»: «Your request parameters didn’t validate.»,
«invalid-params»: [ {
«name»: «age»,
«reason»: «must be a positive integer»
},
{
«name»: «color»,
«reason»: «must be ‘green’, ‘red’ or ‘blue'»}
]
}
`

Подход «Бизнес ошибки отдельно, технические ошибки отдельно»

  • Правильное разделение на уровни абстракции
  • Грамотное удовлетворение потребностей в информации разных групп пользователей
  • Прозрачность к техническим способам доставки информации
  • Проще построить эффективный мониторинг и разграничить доступ к информации

Обработка бизнес-ошибок

Недостатки разделения ошибок от HTTP кодов

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

советы партнёрам Битрикс24 при внедрении и эксплуатации

Задачи со стороны бизнеса
— снизить стоимость проекта по внедрению приложения у клиента;

Для кого статья
— Партнёры Битрикс24, осуществляющие внедрение приложения у клиентов;
— Сотрудники IT-отделов со стороны клиента, которые отвечают за работу Битрикс24;

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

Требования к настройкам бизнес-процессов

  1. Каждый вызов активити приложения должен заканчиваться записью отладочной информации в журнал работы бизнес-процесса, это стандартное активити «Запись в отчет». 
  2. Если бизнес-процесс разветвлённый, то в журнал БП должны быть добавлены записи, позволяющие понять, по какой «ветке БП» пошло исполнение

Почему это важно: активити БП которые ставит приложение это, по сути, удалённый вызов API-метода (функции), он может закончиться как успешно, так и ошибкой. Причин ошибки много: нарушение работы сети, ошибки уровня «приложения», логические ошибки в бизнес-логике, например — попытка начислить бонусы на заблокированную карту. Именно для этого все активити приложения возвращают расширенную отладочную информацию для записи в журнал работы БП.

Каждое активити приложения возвращает стандартные поля для отладки его работы:

  • operation_status_code — статус работы приложения, тип строка, перечисление (error или success)
  • operation_status_message  — текстовое сообщение с описанием результата операции в виде понятном обычному менеджеру 
  • activity_return_result  — массив переменных, которые возвращены приложением как результат работы активити

Пример: Ошибка при настройке бизнес-процесса в Битрикс24

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

Ошибки в настройке бизнес-процесса - активити вернуло результат работы, но его не записали в системный журнал

Пример: корректная настройка бизнес-процесса в Битрикс24

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

Пример записи результатов работы активити Битрикс24 в журнал работы  БП

Запись в журнал работы БП результата его вызова

Пример журнала работы бизнес-процесса для приложения Бонусные карты и программа лояльности для Битрикс24

Порядок диагностики Ошибки при работе бизнес-процесса

  1. Посмотреть в лог работы конкретного бизнес-процесса
  2. Добавить отладочные записи после вызова каждого активити приложения
  3. Посмотреть в системный журнал приложения с использованием утилит для интеграторов.
  4. В случае если ошибка действительно есть и она на стороне приложения, то связаться с технической поддержкой передав ей информацию для диагностики

Что нужно передать технической поддержке приложения для диагностики ошибки

  1. Скриншот бизнес-процесса или его части где есть ошибка
  2. Содержимое лога работы бизнес-процесса с отладочной информацией по вызовам активити
  3. Ссылку на эксельку с B24io.Loyalty — B24 partner dashboard и информацию за какой период времени нужно смотреть системный журнал приложения.
  4. При необходимости — доступы в портал где ошибка воспроизводится

Понравилась статья? Поделить с друзьями:
  • Ошибка в беговой дорожке e01
  • Ошибка в бдо попробуйте позже
  • Ошибка в бателфилд 4 mantle function
  • Ошибка в баскетболе быстрое ведение мяча
  • Ошибка в банкомате альфа банк