防止 DELETES 绕过 Amazon QLDB 中的版本控制
Prevent DELETES from bypassing versioning in Amazon QLDB
Amazon QLDB 允许通过 ID 查询特定对象的版本历史记录。但是,它也允许删除对象。看起来这可以用来通过删除和创建新对象而不是更新对象来绕过版本控制。
例如,假设我们需要通过 VIN 跟踪车辆登记。
INSERT INTO VehicleRegistration
<< {
'VIN' : '1N4AL11D75C109151',
'LicensePlateNumber' : 'LEWISR261LL'
} >>
然后我们的应用程序可以通过查询获取 VIN 的所有 LicensePlateNumber 分配的历史记录:
SELECT * FROM _ql_committed_VehicleRegistration AS r
WHERE r.data.VIN = '1N4AL11D75C109151';
这将 return 所有未删除的文档修订,给我们一个不可伪造的历史。如果您记得插入的文档 ID,则可以类似地使用 history
函数。但是,如果我想恶意绕过历史记录,我会简单地删除该对象并重新插入它:
DELETE FROM VehicleRegistration AS r WHERE VIN = '1N4AL11D75C109151';
INSERT INTO VehicleRegistration
<< {
'VIN' : '1N4AL11D75C109151',
'LicensePlateNumber' : 'ABC123'
} >>
现在没有记录说我修改了这个车牌,违背了QLDB的全部目的。新记录的文档 ID 将与旧记录不同,但 QLDB 无法告诉我们它已更改。我们可以使用一个单独的系统来跟踪文档 ID,但现在另一个系统将成为权威系统而不是 QLDB。我们应该使用 QLDB 来构建这些类型的权威记录,但其他系统也会有完全相同的问题!
如何使用 QLDB 可靠地检测数据修改?
将 是原始记录及其在分类帐中删除的记录,如您所指出的,可以通过 history() 函数获得。所以没有办法隐藏不良行为。这是一个希望没有人知道寻找它的问题。同样,正如您所指出的。
这里有几个选项。首先,QLDB 上周推出了细粒度访问控制 (announcement here). This would let you, say, prohibit deletes on a given table. See the documentation.
您可以做的另一件事是使用 streaming 实时查找删除或其他可疑 activity。您可以将分类帐与 Kinesis Data Stream 相关联。 QLDB 会将每个已提交的事务推送到流中,您可以在其中使用 Lambda 函数对其做出反应。
如果您不需要实时检测,您可以使用 QLDB 做一些事情 export feature. This feature dumps ledger blocks into S3 where you can extract and process data. The blocks contain not just your revision data but also the PartiQL statements used to create the transaction. You can setup an EventBridge scheduler to kick off a periodic export (say, of the day's transactions) and then churn through it to look for suspicious deletes, etc. This lab 可能会有所帮助。
我认为最好的方法是使用权限来管理它。让开发人员退出生产或让他们担任临时角色以获得有限的访问权限。
Amazon QLDB 允许通过 ID 查询特定对象的版本历史记录。但是,它也允许删除对象。看起来这可以用来通过删除和创建新对象而不是更新对象来绕过版本控制。
例如,假设我们需要通过 VIN 跟踪车辆登记。
INSERT INTO VehicleRegistration
<< {
'VIN' : '1N4AL11D75C109151',
'LicensePlateNumber' : 'LEWISR261LL'
} >>
然后我们的应用程序可以通过查询获取 VIN 的所有 LicensePlateNumber 分配的历史记录:
SELECT * FROM _ql_committed_VehicleRegistration AS r
WHERE r.data.VIN = '1N4AL11D75C109151';
这将 return 所有未删除的文档修订,给我们一个不可伪造的历史。如果您记得插入的文档 ID,则可以类似地使用 history
函数。但是,如果我想恶意绕过历史记录,我会简单地删除该对象并重新插入它:
DELETE FROM VehicleRegistration AS r WHERE VIN = '1N4AL11D75C109151';
INSERT INTO VehicleRegistration
<< {
'VIN' : '1N4AL11D75C109151',
'LicensePlateNumber' : 'ABC123'
} >>
现在没有记录说我修改了这个车牌,违背了QLDB的全部目的。新记录的文档 ID 将与旧记录不同,但 QLDB 无法告诉我们它已更改。我们可以使用一个单独的系统来跟踪文档 ID,但现在另一个系统将成为权威系统而不是 QLDB。我们应该使用 QLDB 来构建这些类型的权威记录,但其他系统也会有完全相同的问题!
如何使用 QLDB 可靠地检测数据修改?
将 是原始记录及其在分类帐中删除的记录,如您所指出的,可以通过 history() 函数获得。所以没有办法隐藏不良行为。这是一个希望没有人知道寻找它的问题。同样,正如您所指出的。
这里有几个选项。首先,QLDB 上周推出了细粒度访问控制 (announcement here). This would let you, say, prohibit deletes on a given table. See the documentation.
您可以做的另一件事是使用 streaming 实时查找删除或其他可疑 activity。您可以将分类帐与 Kinesis Data Stream 相关联。 QLDB 会将每个已提交的事务推送到流中,您可以在其中使用 Lambda 函数对其做出反应。
如果您不需要实时检测,您可以使用 QLDB 做一些事情 export feature. This feature dumps ledger blocks into S3 where you can extract and process data. The blocks contain not just your revision data but also the PartiQL statements used to create the transaction. You can setup an EventBridge scheduler to kick off a periodic export (say, of the day's transactions) and then churn through it to look for suspicious deletes, etc. This lab 可能会有所帮助。
我认为最好的方法是使用权限来管理它。让开发人员退出生产或让他们担任临时角色以获得有限的访问权限。