Authentication Bypass by Primary Weakness in firefly-iii/firefly-iii

Valid

Reported on

Oct 23rd 2021


Description

Firefly 3 allows users to register OAuth clients. However, Firefly allows duplicate client names to be registered into the application. Hence, attackers from a different account (assuming registration is enabled) can register a client with duplicate client name and trick the user into accepting the authorization request, gaining access to their account.

Proof of Concept

1: Two accounts. Register OAuth client "Legit Application" onto account 1.

2: Register OAuth client "Legit Application" onto account 2 with redirect_uri as http://[MALICIOUS-SERVER].

3: On session with account 1, access the following link:

http://10.0.2.15/oauth/authorize?response_type=code&redirect_uri=http://[MALICIOUS-SERVER]&client_id=2

4: Notice that the OAuth prompt still uses "Legit Application" name, which user Account 1 would implicitly trust.

Image

5: If the attacker manages to retrieve the auth code through the GET request to the malicious server via the victim clicking the button then they can send it together with their client secret to retrieve the access token.

Image

6: And with the access_token, by using it in the Authorization: Bearer header I can now access API as my victim account

Image

The following are the available APIs (from your Swagger document) which Auth bearer header can be used with: https://api-docs.firefly-iii.org/#/about/getCurrentUser

Impact

An attacker can send the OAuth link to a user in an email and allow the attacker to interact with the API using the victim account via tricking them into accepting the OAuth authorization with a duplicate client name which they trust.

Recommended Fix:

Either display OAuth redirect_uri in the authorization page or prevent duplicate client names.

We have contacted a member of the firefly-iii team and are waiting to hear back a month ago
James Cole
a month ago

Maintainer


Does it actually hand over data?

haxatron
a month ago

Researcher


If the attacker manages to retrieve the auth code by the victim clicking the button then he can send it together with their client secret to retrieve the access token.

(Image)[https://drive.google.com/file/d/1EZN6hMkZCok6x_ySSmZFx7LPxUvU2_z5/view?usp=sharing]

haxatron
a month ago

Researcher


And with the access_token, by using it in the Authorization: Bearer header I can now access the API as the user

https://drive.google.com/file/d/1MyQC4Sq6qQ7kJAK3WtSW-IDtXqVtkxOV/view?usp=sharing

The following are the available APIs (from your Swagger document) which Auth bearer header can be used with: https://api-docs.firefly-iii.org/#/about/getCurrentUser

haxatron modified their report
a month ago
haxatron modified their report
a month ago
haxatron modified their report
a month ago
James Cole
a month ago

Maintainer


OK. How did you get the original users client secret? So user 1, not user 2.

haxatron modified their report
a month ago
haxatron
a month ago

Researcher


Hi there, as a registered user I register a client with duplicate name and it comes along with the client secret. Lets say this is client_id 2. All i need is for the user to click on my URL:

http://10.0.2.15/oauth/authorize?response_type=code&redirect_uri=http://[MALICIOUS-SERVER]&client_id=2

And then I receive the authorization code.

I now can complete the OAuth request.

James Cole
a month ago

Maintainer


Ok so you just happen to know the apps name from user one?

I mean theoretically it could work, and I’ll check it out but this is very far fetched not gonna lie.

haxatron
a month ago

Researcher


So what I mean is User 2 the attacker sets up a malicious client with duplicate name and so should know the client_secret. Then User 2 sends the link to User 1. When User 1 clicks authorize, User 2 receives User 1 authorization code and thus can complete the OAuth process to takeover User 1's account

haxatron
a month ago

Researcher


The PoC is a representation of the attack scenario.

The attack scenario would be for example a public website which is integrated with a Firefly 3 instance and which User 1 and User 2 can both access. As such User 2 can start an OAuth process on the public website and find out the name of the client the public website is registered as.

haxatron modified their report
a month ago
haxatron modified their report
a month ago
James Cole
a month ago

Maintainer


I'm going to ask @admin if I should validate this. I see the issue, although I think the sun will swallow the earth before somebody will execute this. However, it more depends on people being stupid because there's no explanation on how the attacker gets hold of the victim's original token name.

I mean I can edit the popup so the redirect URL is shown, which is a fair precaution and a good idea. But the attack scenario is entirely unrealistic imo.

haxatron
a month ago

Researcher


Alright then, and so, I will summarise the conditions and expected impact for this attack:

Conditions:

  • Attacker must know the client_name of the OAuth the victim will implicitly trust, this can be identified through various means such as the scenario I described above or through information gathering means
  • Attacker must be able to register an account on the platform.

Impact:

  • By making the user visit the link and click "authorize" on the OAuth prompt, then the attacker will obtain authorization code and access token which can be used to takeover the victim's account (If you think about it, this has the same impact as the commonly exploited redirect_uri in OAuth mechanisms, as that too relies on tricking the user to implicitly trust the OAuth prompt and click authorize), and in your application, there is no differentiation between the OAuth prompt of a fake client and the OAuth prompt of a real client.
Jamie Slome
a month ago

Admin


@jc5 - if you believe that the exploit scenario is extremely difficult and unlikely, and borders on not being a security issue, i.e. more of an opinionated stance, feel free to mark as invalid.

If you believe that it does have concerning security implications, we would recommend leaning on the side of valid, but we typically always try to leave it up to the maintainer, and not take a position on the validity of security issues.

Let me know if you have any further questions! 🤗

James Cole validated this vulnerability a month ago
haxatron has been awarded the disclosure bounty
The fix bounty is now up for grabs
James Cole confirmed that a fix has been merged on e9e9a3 a month ago
James Cole has been awarded the fix bounty
authorize.twig#L1L102 has been validated
James Cole
a month ago

Maintainer


No matter how I feel, it would be kind of hypocritical to not acknowledge the issue but then submit code to fix it. ^^