"赶上所有其他" Firebase数据库规则

时间:2016-08-22 14:45:30

标签: firebase firebase-realtime-database firebase-security

也许我从SQL的角度来解决这个问题太多了,但是我很难理解如何正确地限制哪些孩子应该被允许填充节点。

假设我想保留具有任意名称的产品记录。每个产品必须包含price,但不允许任何其他内容。

我天真的方法是向需要newData的产品添加.validate规则以包含price子项,明确授予对price节点的写访问权限,然后删除所有访问{ {1}}节点(有点像switch语句中的default子句):

$other

这不起作用。添加{ "rules": { "$product": { ".read": true, ".write": true, ".validate": "newData.hasChildren(['price'])", "price": { ".write": true, ".validate": "newData.isNumber()" }, "$other": { ".read.": false, ".write": false, } } } } 的新产品仍然可以接受。 但是如果我向{"price": 1234, "foo": "bar"}添加".validate": false规则,则不接受任何内容(例如,不允许$other)。 (我做错了,不知。)

有没有办法实现类似于我在这里尝试的东西?如果没有,在Firebase中限制数据结构的正确方法是什么?我应该这样做吗?如果我不这样做,是什么阻止用户用垃圾填充我的数据库?

1 个答案:

答案 0 :(得分:7)

这里有一些常见的Firebase安全漏洞。最常见的一种是权限级联:一旦您在树中的某个级别上授予了读取或写入权限,就不能在较低级别上取消该权限。

这意味着这些规则无效(因为您已经授予读/写一级更高级别):

"$other": {
    ".read.": false,
    ".write": false,
}

要解决此问题,您必须意识到.validate规则不同:只有在满足所有验证规则时,才认为数据有效。因此,您可以使用验证规则拒绝$other数据:

{
    "rules": {
        "$product": {
            ".read": true,
            ".write": true,
            ".validate": "newData.hasChildren(['price'])",
            "price": {
                ".validate": "newData.isNumber()"
            },
            "$other": {
                ".validate": false
            }
        }
    }
}