Last year I revamped my blog with a new design and a Firebase Realtime Database. It was a fairly smooth ride with some minor complications along the way. As for setting up the database, I found some awesome tutorials that eventually helped me filter it all down to some pretty simple steps.
The blog was running as planned, until one day I received an email from the Firebase team telling me the rules I had set for my database were insecure.
I was confused, so I did what I usually do when I try to get to the bottom of things:
- I read through a bunch of articles.
- Played trial and error with variations of rules.
- Posted on the Firebase community chat.
- Went back and forth with the lovely Firebase support team.
Finally, after weeks of those daily emails, they stopped. Let's take a look at what database setup and rules finally secured them.
The only information my database stores is in regards to the posts. It looks like this:
If you've looked through the documentation for Firebase's security rules, you may be familiar with the read / write set up. My website is a public blog, with no authentication or collecting data from the user of any kind. So, I only needed read requests to be allowed, but any write requests would be denied as I maintain the adding of new blog posts via uploading a new json file in the console.
So, my rules look like this:
Obviously, my auth.uid
is greyed out. You might be wondering where I got that id from. I opened up my project on the Firebase console, clicked on 'Authentication' on the left menu and set up one user - myself. Under the 'User UID' column you will find the auth.uid
. However, as I mentioned I don't have authentication set up for my website, so you may be able to get by without doing this step. If you read on, you'll see the biggest security step was not this auth.uid
, but the addition of posts
in my rules. Try out both and see what happens.
It's important to note I then also had to change the way I requested data from the database in my useEffect()
hook. All I had to do was add the word 'posts' after the /
when requesting the slug:
useEffect(() => {
db.ref()
.child(`/posts/${slug}`)
// ...rest of code
}, []);
If you'd like to see the rest of my useEffect() hook and how it all works together to retrieve and place data, check out my post on Reading and Writing from a Database with React.
Previously, I was doing .child('/${slug}')
. When speaking to the Firebase support team, I was informed that requesting from the root node of my database is what was causing the security vulnerability. So, adding another node called 'posts' between the root level and the posts secured it. Before, I didn't have the posts
node in the rules or database and it went straight to all the posts objects.
And that's all! Now my rules are secure. π I feel better about not contributing to security leaks but better yet I no longer get those worrisome emails.
Note: If you have authentication set up or require extensive database layering and security rules, this is a good blog post to refer to.
Top comments (2)
Loved your blog and subscribed tooπ . I would suggest with you some slight changes if you can do it will look cool.
Thank you Rahul! That's a great tip, will add it to my next update :)