diff --git a/README.md b/README.md index e5a4ae85..d621ee93 100644 --- a/README.md +++ b/README.md @@ -113,6 +113,7 @@ Professional support for Rdiffweb is available by contacting [IKUS Soft](https:/ * Fix loading of Charts in Status page * Ensure Gmail and other mail client doesn't create hyperlink automatically for any nodification sent by Rdiffweb to avoid phishing - credit to [Nehal Pillai](https://www.linkedin.com/in/nehal-pillai-02a854172) * Sent email notification to user when a new SSH Key get added - credit to [Nehal Pillai](https://www.linkedin.com/in/nehal-pillai-02a854172) +* Ratelimit "Resend code to my email" in Two-Factor Authentication view - credit to [Nehal Pillai](https://www.linkedin.com/in/nehal-pillai-02a854172) ## 2.5.4 (2022-12-19) diff --git a/rdiffweb/controller/page_pref_mfa.py b/rdiffweb/controller/page_pref_mfa.py index fb4d9ffd..1f20e68b 100644 --- a/rdiffweb/controller/page_pref_mfa.py +++ b/rdiffweb/controller/page_pref_mfa.py @@ -107,6 +107,7 @@ def validate(self, extra_validators=None): class PagePrefMfa(Controller): @cherrypy.expose + @cherrypy.tools.ratelimit(methods=['POST']) def default(self, action=None, **kwargs): form = MfaToggleForm(obj=self.app.currentuser) if form.is_submitted(): diff --git a/rdiffweb/core/config.py b/rdiffweb/core/config.py index cc2d78fd..1b9f0e5f 100644 --- a/rdiffweb/core/config.py +++ b/rdiffweb/core/config.py @@ -471,7 +471,7 @@ def get_parser(): metavar='LIMIT', type=int, default=20, - help='maximum number of requests per hour that can be made on sensitive endpoints. When this limit is reached, an HTTP 429 message is returned to the user or the user is logged out. This security measure is used to limit brute force attacks on the login page and the RESTful API.', + help='maximum number of requests per hour that can be made on sensitive endpoints. When this limit is reached, an HTTP 429 message is returned to the user or the user is logged out. This security measure is used to limit brute force attacks on the login page and the RESTful API. default: 20 requests / hour', ) parser.add( diff --git a/rdiffweb/tools/ratelimit.py b/rdiffweb/tools/ratelimit.py index 0ec87ed8..6fab2cfe 100644 --- a/rdiffweb/tools/ratelimit.py +++ b/rdiffweb/tools/ratelimit.py @@ -150,7 +150,10 @@ def check_ratelimit( cherrypy.request.app._ratelimit_datastore = datastore # If user is authenticated, use the username else use the ip address - token = (request.login or request.remote.ip) + '.' + (scope or request.path_info) + identifier = request.remote.ip + if hasattr(cherrypy.serving, 'session') and cherrypy.serving.session.get('_cp_username', None): + identifier = cherrypy.serving.session.get('_cp_username', None) + token = identifier + '.' + (scope or request.path_info) # Get hits count using datastore. hits = datastore.get_and_increment(token, delay, hit)