Hi y'all, how are you doing? Hope you are doing great 🤗
It's been quite a long time since my last released blog, mostly because I didn't like the themes I've been coming up with. But today, I'm here to share the process that recently got me to find CVE-2022-3019, a bug that isn't complex at all, but is definitely something cool to spot as a hunter.
🧐 Doing Some Code Review
The whole story started by reading huntr's hacktivity page. I've never thought about testing Low/No Code App Builders before, and it just came to my mind after reading an interesting report there. So I decided to look for bugs in ToolJet, starting with a specific one: IDORs.
In order to do so, whenever I have access to the source code of a web app, I assume that every routine handling requests like this may be a good IDOR candidate:
function showObject(request)
object = Entity.findOrFail(request.params.id)
return object
Why is it an IDOR candidate? Well, because apparently the only check that's being done by this routine is whether the object exists or not, there is absolutely no authorization check. It's not always that simple, because not every application handles authorization within the context of a service's function, but most web apps do it like this.
With this perfect scenario in mind, I went to the code of ToolJet's controllers, and ended up finding a very similar case. The getComment()
method in the Comments Controller had only an authentication middleware, and no checks after that. So after creating an account, theoretically, I could read arbitrary comments even if they were not from the same tenant as my account.
Cool, Breno. And this is the part when you report the super duper critical IDOR you just found, right? 🥳
Definitely not. Because reading arbitrary comments, in my honest opinion, doesn't have any impact. Usually, when we are building stuff cooperatively, the kind of comments that we make doesn't contain sensitive information, and when it does, it's not in a way that can make sense to possible attackers.
👀 Looking for Impact
So reading everybody's comments, by itself, is not a huge of an issue. But what else can we do with it?
I ran an instance of ToolJet, created an account, then I created a comment and looked at the request that had this IDOR, in order to see what data was being retrieved to the browser. Surprisingly, this is what I received:
It was not only an IDOR, but also a case of Excessive Data Exposure! We got email and password hash being disclosed, and the worst part: we got the password reset token also being leaked! 😱
At that moment, this token attribute had a null value, but this got me thinking: what if I, as another user, pick up the email value and use it in the "forgot password?" page? Maybe it'll generate a token that I can see with this comment endpoint
. And that's what I tried.
I created a new account, accessed the comment, got the email of the first account from there, went to the "forgot password" page and pasted that email, then I accessed the comment again and boom! The generated password reset token was there! 🥳
From this point, it was just a matter of accessing the url of password reset with the generated token, and then I was able to change the password of the first user, and impersonate it 🕵️
💡 Final Thoughts
I really like this finding, and I probably would never have found it, if it wasn't for public reports showing me new kinds of apps we can test. Some bug bounty platforms have these amazing hacktivity pages, but we can also discover these cool things from youtube videos, blogs, articles, etc. So...always try to absorb content that is publicly available, it tend to be worth it 🤗
Also, the whole test started with a simple code review, and that's something that I usually try to do when looking for bugs in open source software. If it's something that interests you, I have this series on OWASP API Top 10, with some cool stuff that you can look for when hunting for bugs in APIs. Just a few topics include pseudocode examples (see API3:2019 and API6:2019), but there's also some other stuff that you can test when in a live and running application!
Top comments (0)