【问题标题】:Does Serializable isolation level protect databases against ACIDRain attack?Serializable 隔离级别是否保护数据库免受 ACIDRain 攻击?
【发布时间】:2019-08-14 22:53:33
【问题描述】:

ACIDRain attack paper by Todd Warszawski, Peter Bailis.

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

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

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

  1. 基于级别的隔离异常,这是由于隔离造成的竞争 数据库级别的设置,即数据库可能不支持 可串行化,或者可能没有被配置为这样做(这是 大多数已部署数据库的情况)。
  2. 范围隔离 异常,当应用程序程序员未能 使用事务正确封装逻辑。这使 影响不可能发生的行为的并发请求 按顺序排列。

听起来两者都可以通过对事务强制执行可序列化隔离级别来解决。这是正确的吗?

另外,一些数据库没有真正的 Serializable 隔离级别,例如 Oracle。可以做些什么来保护他们免受此类攻击?

【问题讨论】:

  • @APC 在 Oracle 中使用 Serializable 隔离可能会出现写入偏差。 Link

标签: mysql oracle postgresql serializable transaction-isolation


【解决方案1】:

要使用 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 readsFOR UPDATE 查询选项来避免竞争条件。这可确保从您读取数据时开始对数据进行独占访问。

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

参考资料:

【讨论】:

  • 这是否也适用于 postgresql?
  • 我建议你找到 PostgreSQL 文档,了解他们如何实现 SERIALIZABLE。
  • 我认为这个答案具有误导性。您所要做的就是正确编写您的应用程序,然后它就不会受到这些攻击。没有必要实际序列化所有数据库访问。困难的部分当然是证明应用程序是安全的。
【解决方案2】:

在 PostgreSQL 中,情况很简单:如果您使用SERIALIZABLE 隔离级别,您将自动免受此类攻击。这是因为 PostgreSQL 中的SERIALIZABLE 保证了“真正的”可串行化:如果所有涉及的事务都在该级别运行,则工作负载的结果相当于事务的一些序列化执行。不可能有异常。

你付出的代价是双重的:

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

  • 您必须准备好重复每个事务,以防收到“序列化错误”。

当然,如果一个应用程序根本不使用事务,就没有办法让它安全......

【讨论】:

    猜你喜欢
    • 2019-12-31
    • 2017-04-07
    • 2014-05-23
    • 2010-11-04
    • 2011-10-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多