Serializable隔离级别是否可以保护数据库免受ACIDRain攻击?

问题描述 投票:2回答:2

ACIDRain attack paper by Todd Warszawski, Peter Bailis.

A high-level overview blogpost在这篇论文上。

发现许多应用程序容易受此影响,例如。 WooCommerce,Opencart。

ACIDRain攻击可能会触发两种类型的异常,具体取决于所涉及的应用程序:

  1. 基于级别的隔离异常,这是由于数据库级别的隔离设置导致的竞争,即数据库可能不支持可串行化,或者可能未配置为这样做(对于大多数已部署的数据库而言都是这种情况)。
  2. 范围隔离异常,当应用程序员无法使用事务正确封装逻辑时发生。这使并发请求能够影响无法顺序出现的行为。

听起来两者都可以通过强制执行Serializable隔离级别来解决。这是对的吗?

此外,某些数据库没有真正的Serializable隔离级别,例如Oracle。可以采取哪些措施来保护他们免受此类攻击?

mysql oracle postgresql serializable transaction-isolation
2个回答
3
投票

要使用SERIALIZABLE来保证真正的串行事务,每个事务都必须获取数据库中所有表的全局锁。没有办法事先知道您的交易将尝试读取或更新哪些数据,因此全局锁定是唯一真正的保证。

Oracle和MySQL都有一个事务隔离级别,他们称之为SERIALIZABLE,但他们采取乐观的策略。虽然每个都以不同的方式这样做,但我没有如上所述的全局锁定。

MySQL以一种简单的方式实现SERIALIZABLE:每个SELECT都是隐含的SELECT...LOCK IN SHARE MODE(在8.0中称为SELECT...FOR SHARE)。这意味着如果两个会话读取数据然后尝试更新它,如本文中的余额借记示例所示,它们将导致死锁,因为两个更新都将等待另一个释放其共享读锁定。

Oracle允许您读取和更新数据,并乐观地获取锁(即在您阅读或更新时)。但是,如果您尝试更新自事务开始以来已修改的数据,则会收到以下错误:

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

在Oracle和MySQL中,ACIDRain漏洞的最佳补救措施与隔离级别无关。解决方法是使用explicit locking reads查询选项使用FOR UPDATE来避免竞争条件。这确保了在您读取数据时从数据开始的独占访问。

另一种解决方法是发出显式的表锁定命令,例如MySQL中的LOCK TABLES或Oracle中的LOCK TABLE

参考文献:


2
投票

在PostgreSQL中,情况很简单:如果你使用SERIALIZABLE隔离级别,你可以自动防止这种攻击。这是因为PostgreSQL中的SERIALIZABLE保证了“真正的”可串行化:如果涉及的所有事务都在该级别运行,则工作负载的结果等同于某些序列化的事务执行。没有异常是可能的。

您支付的价格是双重的:

  • SERIALIZABLE会产生额外的费用,因为必须保持谓词锁定。
  • 如果收到“序列化错误”,您必须准备好重复每个事务。

当然,如果应用程序根本不使用事务,则无法使其安全......

© www.soinside.com 2019 - 2024. All rights reserved.