Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

#2783 limit number of failed login and reset password requests #2791

Merged

Conversation

OskarKocjan
Copy link
Contributor

Changes:

  • added single window (IP) rate limiters to sign-in, sign-up, reset password request
  • added a new collection "failed_attempts" which holds states how many attempts were made for each of the previously mentioned endpoints from different IPs
  • added function which controls how many attempts were made to the sign-in and reset password request endpoints and blocks it when the number of failed requests exceeds set amount

@OskarKocjan OskarKocjan self-assigned this Aug 2, 2022
@OskarKocjan OskarKocjan changed the title 2783 limit number of failed login and reset password requests #2783 limit number of failed login and reset password requests Aug 2, 2022
@codecov-commenter
Copy link

codecov-commenter commented Aug 3, 2022

Codecov Report

Merging #2791 (5a7ad5b) into main (a9b141e) will decrease coverage by 4.14%.
The diff coverage is 41.66%.

@@            Coverage Diff             @@
##             main    #2791      +/-   ##
==========================================
- Coverage   63.01%   58.87%   -4.15%     
==========================================
  Files          18      114      +96     
  Lines        1214     4532    +3318     
  Branches      187     1227    +1040     
==========================================
+ Hits          765     2668    +1903     
- Misses        449     1864    +1415     
Impacted Files Coverage Δ
.../components/AcknowledgmentsPage/helperFunctions.ts 0.00% <0.00%> (ø)
...cation/curator-service/api/src/controllers/auth.ts 45.73% <14.28%> (-2.92%) ⬇️
...ervice/api/src/util/single-window-rate-limiters.ts 37.50% <37.50%> (ø)
...n/curator-service/api/src/model/failed_attempts.ts 53.84% <53.84%> (ø)
...tion/curator-service/ui/src/components/Profile.tsx 88.88% <100.00%> (ø)
...src/components/landing-page/ChangePasswordForm.tsx 80.00% <100.00%> (ø)
...vice/ui/src/components/landing-page/SignUpForm.tsx 74.62% <100.00%> (ø)
...fication/curator-service/ui/src/redux/app/slice.ts 75.86% <0.00%> (ø)
...ce/ui/src/components/landing-page/PartnerLogos.tsx 100.00% <0.00%> (ø)
... and 91 more

Help us with your feedback. Take ten seconds to tell us how you rate us. Have a feature suggestion? Share it here.

Copy link
Contributor

@maciej-zarzeczny maciej-zarzeczny left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Everything works fine, the messages telling about going over the requests limit are showing fine on the frontend. I left some comments about code

Copy link
Contributor

@maciej-zarzeczny maciej-zarzeczny left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great work! 💯

Copy link
Contributor

@abhidg abhidg left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good, not sure about some of the enums -- and the time limit windows vary


updateFailedAttempts(
user._id,
AttemptName.ResetPassword,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should be ForgotPassword

// Check if token exists
const passwordResetToken = await tokens().findOne({
userId,
});
if (!passwordResetToken) {
updateFailedAttempts(
userId,
AttemptName.ForgotPassword,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ResetPassword? not clear what's the difference

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for your input! Of course, I made a mistake and assigned the wrong AttemptNames in sections of code that you highlighted but to answer your question I named them (AttemptName) accordingly:

  • Login - counter for login
  • ResetPassword - counter for resetting a password in a user's profile (already logged in)
  • ForgotPassword - counter for requesting a reset password link that is located on the landing page of the curator portal
  • ResetPasswordWithToken - counter for resetting the password through a form to which the user has access by an email link

const numberTimeLimiters = {
loginAttempt: {
maxNumberOfFailedLogins: 8,
timeWindowForFailedLogins: 60, //min
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Better to put the unit in the property name like timeWindowForFailedLoginsMinutes

import rateLimit from 'express-rate-limit';

export const loginLimiter = rateLimit({
windowMs: 20 * 60 * 1000, // 20 minutes
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this be 60 minutes? It's different from numberTimeLimiters

});

export const resetPasswordLimiter = rateLimit({
windowMs: 30 * 60 * 1000, // 30 minutes
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same here, different from numberTimeLimiters

@abhidg abhidg marked this pull request as ready for review August 15, 2022 14:45
@abhidg abhidg merged commit aa0adec into main Aug 16, 2022
@abhidg abhidg deleted the 2783-limit-number-of-failed-login-and-reset-password-requests branch August 16, 2022 09:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants