0

I was watching the Firebase doc videos and noticed that in this video: https://www.youtube.com/watch?v=9sOT5VOflvQ&list=PLl-K7zZEsYLn8h1NyU_OV6dX8mBhH2s_L&index=4

at 6:39, Doug mentions that it is possible to limit the amount of document returned by one query, by doing something like: allow list if: request.query.limit <= 20

However, he mentions that, although this is beneficial because it prevents you from accidentally executing a very costly set of reads, it still won't prevent malicious users from reading everything in your database by making multiple requests and using pagination to sift through your database. I could envision some sort of infinite while loop in JavaScript that makes this very problematic and costly.

The only way that I could think to solve this problem is by somehow using timestamps perhaps, and saving some information associated with each user which informs the database of when they last made a request. Would it be possible to do this and then access those timestamps in the security rules? Something along the lines of (where the second condition is kind of pseudo-code):

allow list if: request.query.limit <= 20 && get(/databases/$(database)/documents/users/$(request.auth.uid)).data.last-time <= 100

This seems to me the most feasible way but if anyone else has thoughts on this, they would be much appreciated!

Evan
  • 1,892
  • 2
  • 19
  • 40

1 Answers1

1

The problem is that you can't update last-time when this query happens. And since you can't update last-time when they read, there is no way to restrict the number of reads a user can perform through this mechanism.

Because of this limitation it is possible implement a write rate limit in security rules, but not a read rate limit.

Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807
  • ah very true yeah thank you! I can't actually modify the database from the security rules so it is impossible to restrict the number a reads a user can make. Would my best bet then just be to do something like a limit on the number of results returned from a query and if I notice any suspicious behavior just prevent that individual uid from reading anything? – Evan Jan 03 '21 at 19:30
  • 1
    There is no singular "best bet" here, otherwise we would have documented that. :) For most apps I care **a lot** about *what* each user can access, but very little about how much of that they actually access. But if the latter matters more to you, you might consider using Cloud Functions to control such read access. Note that this will make the read operations a lot less simple, so it's a trade-off whether it is worth it to your app. – Frank van Puffelen Jan 03 '21 at 19:35