I've been searching for ways to rate limit requests by IP, but was not able to find any resources. Basically what I'm looking is a way to implement firewall logic. I know that I can limit authenticated user requests with database rules, but how do I go about limiting page hits? For example I only want to allow 150 requests per minute for each IP. Is there any way to do this? Otherwise, wouldn't it be easy to attack small businesses who are on Blaze plan?
Asked
Active
Viewed 4,130 times
2 Answers
18
Firebaser here.
There is currently no way to rate-limit based on IP address with Firebase Hosting. Our CDN partner includes some built-in protection against (D)DoS attacks, but this is not presently configurable.
We find that this generally isn't a problem. If you do run into usage that you suspect is abuse, please reach out to Firebase support and we'll work with you to resolve the situation to everyone's satisfaction.

Michael Bleigh
- 25,334
- 2
- 79
- 85
-
Thanks for the quick reply Michael. I haven't run into any issues as my app is not in production yet. Regarding DDoS attacks, does this mean I don't need free Cloudflare plan or something similar? – tugce Oct 16 '17 at 18:46
-
7Please *don't* put Cloudflare in front of your Firebase Hosting site. We already serve everything from a CDN, so putting another CDN in front of it will actually make it slower! – Michael Bleigh Oct 17 '17 at 01:07
-
1@MichaelBleigh can we put Cloudflare in front of Firebase functions for rate limiting? Thanks! – dowi Jun 28 '20 at 10:15
-
We don't explicitly support putting an additional CDN layer in front of Firebase Hosting, but we do have customers that do so. – Michael Bleigh Jun 29 '20 at 17:30
-
@MichaelBleigh So far, the plan to have cost controls in Firebase has been released? – webmastx Mar 23 '21 at 08:33
-
Updated my answer to remove speculation about future features. – Michael Bleigh Mar 24 '21 at 16:29
3
It seems to be the current rate limit is to use some middleware like express-rate-limiter. Then in your server.ts (or .js if JavaScript) file you can do as follows:
import * as express from 'express';
import * as rateLimit from 'express-rate-limit';
const server: Express = express();
server.set('trust proxy', 1); // Enable because the application is behind reverse proxy (Firebase).
server.use(
rateLimit({
max: 100, // Max 100 connections per windowMs can be done before sending HTTP 429 (Too Many Requests) response code. After 100 requests within 15 minutes block the IP.
message:
'This IP has been temporarily blocked due to too many requests, please try again later.',
windowMs: 15 * 60 * 1000 // In milliseconds, keep records of requests in memory for 15 minutes.
})
);
Alternatively, if you don't want to block the IP, rather slow it down use express-slow-down.

Daniel Danielecki
- 8,508
- 6
- 68
- 94
-
-1 since this won't work out of the box without some kind of custom store. The default in-memory wont work. One would need to code a "Firestore/Realtime DB"-store for it. – DarkNeuron Sep 10 '20 at 11:36
-
@DarkNeuron an example from your side would've been definitely appreciated. Thanks in advance. – Daniel Danielecki Sep 10 '20 at 12:28
-
Well sorry, but your code literally does nothing without a store. The default in-memory store wont work because CF runs using one or more nodes - each with their own memory; and nodes come and go based on load (like any horizontally scaled setup). I can make no examples because I'd have to write that storage layer from scratch. But check out their docs if you want to make your answer great; I'd gladly upvote it. But as it stands, it does nothing. – DarkNeuron Sep 10 '20 at 12:40
-
That's really okay to downvote/criticise. However, if you have certain knowledge about that topic (it looks like that you do more than me) then when you'll write it, a GitHub repo will definitely help for other within that community to handle this issue. Still, thanks for sharing your doubts. Edit: by "storage layer" do you mean `storage.rules` and `firestore.rules`? – Daniel Danielecki Sep 10 '20 at 14:14
-
1No no, I mean the `rateLimit` code you posted above need to persist who did what, in a place other than memory due to the reasons I described. https://www.npmjs.com/package/express-rate-limit describes a few options such as Redis, Mongo etc, but the optimal solution would be Firestore or Realtime DB for obvious reasons. So one would have to write a store like this `https://github.com/wyattjoh/rate-limit-redis/blob/master/lib/redis-store.js`, but for your Firebase DB of choice. – DarkNeuron Sep 11 '20 at 07:44