简体   繁体   English

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

[英]Does Serializable isolation level protect databases against ACIDRain attack?

ACIDRain attack paper by Todd Warszawski, Peter Bailis. 由Todd Warszawski撰写的ACIDRain攻击文件,Peter Bailis。

A high-level overview blogpost on this paper. 本文的高级概述博客文章。

Many applications were found to be vulnerable to this, eg. 发现许多应用程序容易受此影响,例如。 WooCommerce, Opencart. WooCommerce,Opencart。

There are two types of anomaly that ACIDRain attacks could trigger, dependent on the application involved: ACIDRain攻击可能会触发两种类型的异常,具体取决于所涉及的应用程序:

  1. Level-based isolation anomalies, which are races due to isolation settings at the database-level ie the database may not support serializability, or may not have been configured to do so (this is the case for most deployed databases in the wild). 基于级别的隔离异常,这是由于数据库级别的隔离设置导致的竞争,即数据库可能不支持可序列化,或者可能尚未配置为执行此操作(对于大多数已部署的数据库而言是这种情况)。
  2. Scoping isolation anomalies, which occur when an application programmer fails to correctly encapsulate logic using transactions. 范围隔离异常,当应用程序员无法使用事务正确封装逻辑时发生。 This enables concurrent requests to impact behavior that could not have arisen sequentially. 这使并发请求能够影响无法顺序出现的行为。

It sounds like both can be solved by enforcing Serializable isolation level for transactions. 听起来两者都可以通过强制执行Serializable隔离级别来解决。 Is it correct? 这是对的吗?

Also, some database doesn't have real Serializable isolation level, for example Oracle. 此外,某些数据库没有真正的Serializable隔离级别,例如Oracle。 What can be done to protect them from this type of attack? 可以采取哪些措施来保护他们免受此类攻击?

To use SERIALIZABLE to guarantee truly serial transactions, every transaction would have to acquire a global lock on all tables in the database. 要使用SERIALIZABLE来保证真正的串行事务,每个事务都必须获取数据库中所有表的全局锁。 There's no way to know in advance what data your transaction will try to read or update, so a global lock is the only real guarantee. 没有办法事先知道您的交易将尝试读取或更新哪些数据,因此全局锁定是唯一真正的保证。

Both Oracle and MySQL have a transaction isolation level that they term SERIALIZABLE, but they take an optimistic strategy. Oracle和MySQL都有一个事务隔离级别,他们称之为SERIALIZABLE,但他们采取乐观的策略。 Though each does so in different ways, neither does a global lock as I described above. 虽然每个都以不同的方式这样做,但我没有如上所述的全局锁定。

MySQL implements SERIALIZABLE in a simple way: Every SELECT is implicitly SELECT...LOCK IN SHARE MODE (known as SELECT...FOR SHARE in 8.0). MySQL以一种简单的方式实现SERIALIZABLE:每个SELECT都是隐式SELECT...LOCK IN SHARE MODE (在8.0中称为SELECT...FOR SHARE )。 This means that if two sessions read the data and then try to update it as shown in the balance debit example in the paper, they'll cause a deadlock because both updates will be waiting for the other to release its shared read lock. 这意味着如果两个会话读取数据然后尝试更新它,如本文中的余额借记示例所示,它们将导致死锁,因为两个更新都将等待另一个释放其共享读锁。

Oracle allows you to read and update data, and acquires locks optimistically (ie at the time you read or update). Oracle允许您读取和更新数据,并乐观地获取锁(即在您阅读或更新时)。 But if you try to update data that has been modified since your transaction began, you get this error: 但是,如果您尝试更新自事务开始以来已修改的数据,则会收到以下错误:

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

In both Oracle and MySQL, the best remedy for the ACIDRain vulnerability has nothing to do with isolation level. 在Oracle和MySQL中,ACIDRain漏洞的最佳补救措施与隔离级别无关。 The remedy is to avoid the race condition by using explicit locking reads using the FOR UPDATE query option. 解决方法是通过使用FOR UPDATE查询选项使用显式锁定读取来避免竞争条件。 That ensures exclusive access to the data starting at the time you read the data. 这确保了在您读取数据时从数据开始的独占访问。

Another remedy would be to issue explicit table-locking commands, such as LOCK TABLES in MySQL or LOCK TABLE in Oracle. 另一种解决方法是发出显式的表锁定命令,例如MySQL中的LOCK TABLES或Oracle中的LOCK TABLE

References: 参考文献:

In PostgreSQL the case is simple: if you use the SERIALIZABLE isolation level, you are automatically safe from such attacks. 在PostgreSQL中,情况很简单:如果使用SERIALIZABLE隔离级别,则可以自动防止此类攻击。 This is because SERIALIZABLE in PostgreSQL guarantees “true” serializability: if all transactions involved run at that level, the result of the workload is equivalent to some serialized execution of the transactions. 这是因为PostgreSQL中的SERIALIZABLE保证了“真正的”可串行性:如果所涉及的所有事务都在该级别运行,则工作负载的结果等同于事务的某些序列化执行。 No anomalies are possible. 没有异常是可能的。

The price you are paying is twofold: 您支付的价格是双重的:

  • SERIALIZABLE incurs an extra cost, because predicate locks have to be maintained. SERIALIZABLE会产生额外的成本,因为必须保持谓词锁。

  • You have to be ready to repeat every transaction in case you receive a “serialization error”. 如果收到“序列化错误”,您必须准备好重复每个事务。

Of course, if an application doesn't use transactions at all, there is no way to make it safe... 当然,如果应用程序根本不使用事务,则无法使其安全......

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 具有可序列化隔离级别的事务中的死锁 - Deadlock in transaction with isolation level serializable sprintf() 如何防止 SQL 注入? - How does sprintf() protect against SQL injection? 不可重复读取和幻读发生在“SERIALIZABLE”隔离级别(MySQL) - Non-repeatable read and phantom read occur with 'SERIALIZABLE' isolation level (MySQL) MySQL InnoDB 如何实现 Read Uncommitted 隔离级别 - How does MySQL InnoDB implement Read Uncommitted isolation level MySQL - READ UNCOMMITED 隔离级别是否使用锁? - MySQL - Does the READ UNCOMMITED isolation level use locks? 使用更高的隔离级别是否会降低发生死锁的可能性? - Does using higher isolation level decreases the probability of having deadlocks? JSON.stringify字符串是否可以防止(My)SQL注入? - Does JSON.stringify a string protect against (My)SQL injection? Amazon Aurora是否为在从属节点上运行的只读事务提供可序列化隔离? - Does Amazon Aurora offer serializable isolation for read-only transaction running on slave nodes? Zebra_Database MySQL包装器是否可以防止SQL注入? - Does the Zebra_Database MySQL wrapper protect against SQL injection? PHP中的mysqli类是否可以100%防止sql注入? - Does mysqli class in PHP protect 100% against sql injections?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM