Firebase防止垃圾邮件存储

DTh*_*ink 5 firebase firebase-security firebase-storage

我不知道如何设置一天的文件上传限制。我希望用户每天最多发布10张照片。在数据库方面,我放置了一个增量计数器。如果达到一定大小,则不允许用户发布其他内容。但是在存储方面这是不可能的。攻击者可以无限制地发布他想要的所有文件。有防止这种情况的解决方案吗?提前致谢。目前,我的安全规则是:

service firebase.storage {
  match /b/projectid/o {
    match /Photo/{user}/{photo}/image.jpg {
      allow write: if request.auth != null && 
                      request.auth.uid == user && (
                      request.resource.size < 5 * 1024 * 1024 && photo.size() < 32 || 
                      request.resource == null);
      allow read: if request.auth != null && 
                     request.auth.uid == user
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

Mik*_*ald 4

嗯,有一种非常简单的方法可以做到这一点,而且有正确的方法。

只允许在特定时间段内上传一定数量的文件的黑客方法是使用某些数字属性来命名文件:例如users/{userid}/0.jpg通过users/{userid}/9.jpg(对于 10 张照片)。

您可以编写一个规则来检查,如下所示:

// Match all filenames like 0.jpg
match /users/{userId}/{photoId} {
  allow write: if photoId.matches('^\d\.jpg$')
}
Run Code Online (Sandbox Code Playgroud)

如果您需要比数量级更多的粒度,您可以执行以下操作:

// Match all filenames like YYY.jpg where YYY is a number less than XXX
match /users/{userId}/{photoId} {
  allow write: if int(photoId.split('\.')[0]) < XXX
}
Run Code Online (Sandbox Code Playgroud)

但这只解决了我们问题的一半:我们可以限制文件数量,但如果用户只想上传文件怎么办?幸运的是,我们可以编写一条规则来防止最终用户覆盖他们的文件(尽管我们必须排除删除)或在给定的时间段内。让我们探索一下:

// Allow files to be overwritten once a day, written if there's nothing there, or deleted as often as desired
match /users/{userId}/{photoId} {
  allow write: if request.time > resource.timeCreated + duration.value(1, "d") || resource.size == 0 || request.resource.size == 0
}
Run Code Online (Sandbox Code Playgroud)

这些可以组合成函数:

function isAllowedPhotoId(photoId) {
  return int(photoId.split('\.')[0]) < XXX
}

function canOverwritePhoto() {
  return request.time > resource.timeCreated + duration.value(1, "d") || resource.size == 0 || request.resource.size == 0
}

match /users/{userId}/{photoId} {
  allow write: if isAllowedPhotoId(photoId) && canOverwritePhoto()
}
Run Code Online (Sandbox Code Playgroud)

从长远来看,解决方案是能够从存储中引用数据库数据,反之亦然。不幸的是,这个世界还没有到来,但我们正在努力实现这一目标。