Защищает ли Serializable уровень изоляции баз данных от атаки ACIDRain? - PullRequest
3 голосов
/ 24 марта 2019

ACIDRain атаки бумаги Тодд Варшавски, Питер Бейлис.

Обзорный пост на высоком уровне на этой бумаге.

Многие приложения были признаны уязвимыми для этого, например. WooCommerce, Opencart.

Существует два типа аномалий, которые могут вызывать атаки ACIDRain, в зависимости от используемого приложения:

  1. Уровневые аномалии изоляции, которые являются расами из-за изоляции настройки на уровне базы данных, т.е. база данных может не поддерживать сериализуемость или, возможно, не были настроены для этого (это случай для большинства развернутых баз данных в дикой природе).
  2. Обзорная изоляция аномалии, которые возникают, когда программисту приложения не удается правильно инкапсулировать логику, используя транзакции. Это позволяет одновременные запросы на воздействие поведения, которое не могло возникнуть последовательно. * * 1016

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

Кроме того, некоторые базы данных не имеют реального уровня изоляции Serializable, например Oracle. Что можно сделать, чтобы защитить их от атак такого типа?

Ответы [ 2 ]

3 голосов
/ 24 марта 2019

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

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

MySQL реализует SERIALIZABLE простым способом: каждый SELECT неявно SELECT...LOCK IN SHARE MODE (известный как SELECT...FOR SHARE в 8.0). Это означает, что если две сессии прочитают данные, а затем попытаются обновить их, как показано в примере дебетования баланса в статье, они вызовут взаимоблокировку, поскольку оба обновления будут ожидать, пока другая освободит свою общую блокировку чтения.

Oracle позволяет вам читать и обновлять данные, и оптимистически получает блокировки (т.е. во время чтения или обновления). Но если вы попытаетесь обновить данные, которые были изменены с момента начала транзакции, вы получите эту ошибку:

ORA-08177: can't serialize access for this transaction

Как в Oracle, так и в MySQL лучшее средство от уязвимости ACIDRain не имеет ничего общего с уровнем изоляции. Решение проблемы заключается в том, чтобы избежать условия гонки, используя явную блокировку чтения , используя опцию запроса FOR UPDATE. Это обеспечивает эксклюзивный доступ к данным, начиная с момента их чтения.

Другим выходом из ситуации может быть выдача явных команд блокировки таблиц, таких как LOCK TABLES в MySQL или LOCK TABLE в Oracle.

Ссылки:

2 голосов
/ 25 марта 2019

В PostgreSQL случай прост: если вы используете уровень изоляции SERIALIZABLE, вы автоматически защищены от таких атак. Это потому что SERIALIZABLE в PostgreSQL гарантирует & ldquo; true & rdquo; сериализуемость: если все задействованные транзакции выполняются на этом уровне, результат рабочей нагрузки эквивалентен некоторому сериализованному выполнению транзакций. Аномалии не возможны.

Цена, которую вы платите, является двойной:

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

  • Вы должны быть готовы повторить каждую транзакцию в случае, если вы получили & ldquo; ошибку сериализации & rdquo;.

Конечно, если приложение вообще не использует транзакции, нет способа сделать его безопасным ...

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