[英]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攻击可能会触发两种类型的异常,具体取决于所涉及的应用程序:
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.