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

时间:2019-03-24 15:15:47

标签: mysql oracle postgresql serializable transaction-isolation

ACIDRain attack paper by Todd Warszawski, Peter Bailis.

A high-level overview blogpost在本文上。

许多应用程序容易受到此攻击,例如。 WooCommerce,Opencart。

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

  1. 基于级别的隔离异常,这是由于隔离引起的种族 数据库级别的设置,即数据库可能不支持 可序列化,或可能尚未配置成可序列化(这是 对于大多数已部署的数据库而言)。
  2. 作用域隔离 异常,当应用程序程序员无法执行时 使用事务正确封装逻辑。这使 并发请求以影响可能不会发生的行为

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

此外,某些数据库没有真正的可序列化隔离级别,例如Oracle。如何保护他们免受此类攻击?

2 个答案:

答案 0 :(得分: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漏洞的最佳方法与隔离级别无关。补救措施是通过使用FOR UPDATE查询选项使用explicit locking reads来避免争用情况。这样可以确保从读取数据开始就对数据进行独占访问。

另一种补救方法是发出明确的表锁定命令,例如MySQL中的LOCK TABLES或Oracle中的LOCK TABLE

参考文献:

答案 1 :(得分:1)

在PostgreSQL中,情况很简单:如果使用SERIALIZABLE隔离级别,则可以自动免受此类攻击。这是因为PostgreSQL中的SERIALIZABLE保证了“真实”的可串行性:如果所有涉及的事务都在该级别上运行,那么工作量的结果就等同于事务的某些序列化执行。没有异常是可能的。

您要支付的价格是两倍:

  • SERIALIZABLE会产生额外的费用,因为必须维护谓词锁。

  • 如果您收到“序列化错误”,则必须准备重复每笔交易。

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