2amigos / yii2-usuario

Highly customizable and extensible user management, authentication, and authorization Yii2 extension
https://github.com/2amigos/yii2-usuario
Other
294 stars 142 forks source link

Handle PasswordRecoveryService exception #551

Closed Eseperio closed 4 months ago

Eseperio commented 4 months ago

When PasswordRecoveryService does not found user, it throws a RuntimeException, but that is not handled by RecoveryController, which ends up in RuntimeException being throwed to user. It should be wrapped in try catch

Since attackers are performing brute force attacks on that kind of urls, probably using stolen email addresses, we are getting our CloudWatch log full of User not found messages.

Eseperio commented 4 months ago

Seems like attackers are trying to gain access to all the email accounts stolen in data breaches by sending batch requests to /user/forgot. That way they can gain access to platforms from those addresses.

maxxer commented 4 months ago

Can you provide a PR? Tanks

Eseperio commented 4 months ago

I did a PR updating the kind of exception thrown, which is the shortest way to fix the issue with logs.

maxxer commented 4 months ago

Good, thank you. But how this could mitigate the brute force against users? We should maybe introduce a rate limiter to avoid this behaviour

Eseperio commented 4 months ago

Well, i was thinking about implementing Captcha, but that is already a possibility and it is well documented.

Other options can be implementing a delay in that functionality, since it is not a method you use everyday. A simple delay of 3 seconds can limit the ability from attackers from checking 24.000 address per hour to 1200.

Another option is implementing a rate limit filter associated to IP, but one thing a good attacker does is using many IPs for same target.

So what do you think?

maxxer commented 4 months ago

Well, captcha is a good solution I didn't think about.

Let's go with your patch. Can you add a changelog entry? then I'll merge

Eseperio commented 4 months ago

I´ve updated changelog. Check it before merge. I´ll close this issue.

tonydspaniard commented 4 months ago

I would recommend providing a throttling middleware to limit the requests x second providing an increased delay of seconds by number of failed requests (the higher the failed attempts, the higher the delay, after X number of failed attempts, add IP to blocklist), IP middleware blocklist (for recognised brute force attackers IPs), and captcha or other options optional.

Not sure this is part of this package or should be part of a security one.

Eseperio commented 4 months ago

The problem with every limiter comes with storage. Where do you store the amount of retries?

tonydspaniard commented 4 months ago

Temporary log files may be the simplest solution. Having adapters for other storage methods (RRDB, NoSQL, Redis, etc).