Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Firebase : How to secure content sent without login?

I'm building a hybrid mobile app with Firebase as my backend. I want to let users post on a wall any message they want without authentication, but I feel concerned about spam possibilities. I mean, if users don't have to be authenticated to be able to post, my security rules are basically empty and anyone who gets the endpoint can post an infinite amount of content. And I don't see what I could do against it.

So I know about anonymous auth, but I'm not sure if it really fix the issue. The endpoint remains open, after all, just behind the necessity to call a method before. It adds a little complexity but not much, I think.

What I wonder is if there is a possibility to check for the call origin, to make sure it comes from my app and nothing else. Or, if you have another idea to get this more secure, I'm open to everything. Thanks!

like image 448
Jeremy Belolo Avatar asked Dec 03 '25 10:12

Jeremy Belolo


1 Answers

You can accomplish this using a combination of recaptcha on the client, and firebase cloud functions on the backend.

You send the message you want to add to the store along with the captcha to the cloud function. In the cloud function, we first verify the captcha. If this one is ok, we add the message to the store. This works, because when adding items to the store via a cloud function, firebase authentication rules are ignored.

Here's an example cloud function:

const functions = require('firebase-functions')
const admin = require('firebase-admin')
const rp = require('request-promise')
const cors = require('cors')({
    origin: true,
});

admin.initializeApp();

exports.createUser = functions.https.onRequest(function (req, res) {
  cors(req, res, () => {

    // the body is a json of form {message: Message, captcha: string}
    const body = req.body;

    // here we verify whether the captcha is ok. We need a remote server for 
    // for this so you might need a paid plan
    rp({
        uri: 'https://recaptcha.google.com/recaptcha/api/siteverify',
        method: 'POST',
        formData: {
            secret: '<SECRET>',
            response: body.captcha
        },
        json: true
    }).then(result => {
        if (result.success) {
            // the captcha is ok! we can now send the message to the store
            admin.firestore()
                .collection('messages')
                .add(body.message)
                .then(writeResult => {
                    res.json({result: `Message with ID: ${writeResult.id} added.`});
                });
        } else {
            res.send({success: false, msg: "Recaptcha verification failed."})
        }
    }).catch(reason => {
        res.send({success: false, msg: "Recaptcha request failed."})
    })
  });
})

And here's some more info: https://firebase.googleblog.com/2017/08/guard-your-web-content-from-abuse-with.html

like image 173
David Bulté Avatar answered Dec 05 '25 16:12

David Bulté



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!