Discovery: How to avoid users hacking your reset password page?

Hi all,

Wesley from Flusk here :wave:t3:

Did you guys knew that the “Assign a Temporary Password” can represent a huge security vulnerability on your Bubble app?

I’ll tell you about the day I got access to an admin dashboard without being authorized to.

:warning: This post is not made to teach you how to hack Bubble apps. Quite the opposite, it’s here so that everyone knows about it and avoid doing the same mistake on their apps.

One day, I visited a website of a company that was selling online courses.
The problem was on their “reset_pw” page.

If you wanted to reset your password, they would ask for your email and then, use the “Assign a temporary password” action and send the generated random password via email.
Exactly like this:

But this company has done a big mistake configuring it like that. :rotating_light:

Why? Because everything is happening in the front-end.
And everything happening in the front-end is visible to any user.

:thinking: But I don’t know what you mean Wes. How could you log into the admins accounts?

Here it is.
When looking at the Network Tab in your Chrome DevTools, you can see that every action triggered by this workflow results in an API Call to Bubble’s servers.

Here I have 2 steps in my workflow:

  • Assign a temporary password (the red box)
  • Send an email (the blue box)

Result of both steps are returned by Bubble in the result of the “start” request, which starts the chain of actions.

And if we look at the result of step n°1 (which is the “Assign a temporary password” one), we can see here, in plain-text, the new assigned password.

Which means… and know you see it coming…

:bulb: What if I fill the email of an admin user when I want to reset the password, instead of putting my own email?!

If in the “What’s your email?” input I type “admin@company.com”, it WILL reset its password… and I’ll be able to see it in plain-text in the Network Tab of my Chrome DevTools.

Now, I just need to go to the login page and fill the following credentials to be logged in as an admin:

But what’s the solution to this? :exploding_head:

I couldn’t just come up with a security issue without also coming with the associated fix. So there you go :white_check_mark:

It’s actually quite easy (thanks Bubble).

If you know that everything happening in the front-end can be seen by anyone…
Just perform this action in the back-end side of your app.

Let’s go step-by-step through this.

1 - Creating the API Workflow

We’ll go to the back-end section of the app, and create a new API Workflow that we will call “assign-temporary-password”.
It will take a parameter:

  • user-email of type ‘text’

Then, we’ll simply reproduce the exact same behavior than what our initial workflow was doing.
Here’s a screenshot:

2 - Modifying our initial workflow

Now, let’s go back to our previous workflow - the one on the ‘reset_pw’ page.
Let’s delete all the actions inside of it, and make it just trigger our freshly created API workflow and fill in the associated parameter.

And… there we go! :white_check_mark:
The security issue is now fixed and we’re all set :closed_lock_with_key:

:link: Here is the link to the demo app if you’d like to know how to implement it.

:closed_lock_with_key: But that’s not the safest way to work with passwords

As mentioned in Bubble’s official documentation, the most secure way to work with passwords is to use the “Reset Password” action.

Important: This workflow action is meant to be used in a situation where an admin is resetting the password for a user - the admin can see the new password. We do not recommend building this into an end-user-facing flow on a page because it is not a secure way to work with passwords.

If you can implement this logic, that’s the best you can do.
But if you need to use the “Assign a temporary password” in your flow for your specific use-case, you know how to do it in a secure way.
Thanks @sudsy for mentioning this to us!

PS: if you’ve got any question or if there’s anything you don’t understand, feel free to reply to this thread. I’m always happy to help :sunny:


Wesley Wasielewski
CEO & Co-founder at Flusk

:closed_lock_with_key: Automated Security Audits for Bubble.io apps
:chart_with_upwards_trend: Advanced Logs Monitoring and Error Handling for Bubble.io apps
:bird: Twitter/X Account with many Bubble.io security tips

With :heart:

8 Likes

Hi, thanks for your insights.

But out of the blue it seems like not a very good practice to send out a temporary password anyway. Why not recommend the ‘usual’ way of:

  • trigger password reset flow
  • create token that is 24h valid and send it via email (as a backend workflow of course)
  • on the pw_reset page check the token
  • let the user create a new password
  • log the user in if successful or if the 24 hours have passed give the ability to send out another email with another token.

Isn’t this the more or less standard way?

3 Likes

Yeah, my thoughts exactly. In fact, this very scenario is explicitly mentioned in the documentation for the Assign a temp password action, which states…

3 Likes

That’s right @sudsy and @hi_bubble :heavy_check_mark:

However, this was only very recently added to the documentation, and there’s quite a few apps out there that use this method still. That’s why I think it’s still important to remind people to use the flow you mentioned or the one we showcased.

1 Like

It’s a well-written and informative post, @vnihoul77. My only suggestion would be to describe (or at least mention) the “best practice” at the outset, before delving into how to plug the security hole in a “less than ideal” implementation.

BTW, congrats on the new release of Flusk! :slightly_smiling_face:

2 Likes

You’re actually right! I’ll ask @weswas to include it in the post.

We wrote the post thinking of the people using this workflow combination because they have a specific use-case to follow, but there’s definitely plenty that are using it as just an alternative to the flow you’re mentioning!

And thanks! It’s very exciting times for us and we’re excited to bring even more!

Hi @sudsy,

Thanks for your relevant reply.
I’ve just edited the post and added a new section to mention the “Reset Password” action, which is indeed the way you should go when working with passwords. :+1:t3: