CVE-2022-3371 (published 2022-09-30T14:15Z)

Allocation of Resources Without Limits or Throttling in GitHub repository ikus060/rdiffweb prior to 2.5.0a3.

CVSS v3 base score: 7.5, HIGH (CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H)

Weakness information:
cwe_id: CWE-770
cwe_name: Allocation of Resources Without Limits or Throttling
description: The product allocates a reusable resource or group of resources on behalf of an actor without imposing any restrictions on the size or number of resources that can be allocated, in violation of the intended security policy for that actor.
extended_description: Code frequently has to work with limited resources, so programmers must be careful to ensure that resources are not consumed too quickly, or too easily.  Without use of quotas, resource limits, or other protection mechanisms, it can be easy for an attacker to consume many resources by rapidly making many requests, or causing larger resources to be used than is needed. When too many resources are allocated, or if a single resource is too large, then it can prevent the code from working correctly, possibly leading to a denial of service.
         

Fix information:
repo_url: https://github.com/ikus060/rdiffweb
commit_details: repo_url: https://github.com/ikus060/rdiffweb
author: Patrik Dufresne
author_date: 2022-09-25 20:07:21-04:00
msg: Limit user's fullname and Token name field length
repository: repo_url: https://github.com/ikus060/rdiffweb
repo_name: ikus060/rdiffweb
description: A simplified backup management software for quick access to your archives through an efficient web interface.
repo_language: Python
owner: ikus060
file_changes: filename: page_admin_users.py
change_type: ModificationType.MODIFY
diff: @@ -76,7 +76,13 @@ class UserForm(CherryForm):
             validators.length(max=256, message=_('Username too long.')),
         ],
     )
-    fullname = StringField(_('Fullname'), validators=[validators.optional()])
+    fullname = StringField(
+        _('Fullname'),
+        validators=[
+            validators.optional(),
+            validators.length(max=256, message=_('Fullname too long.')),
+        ],
+    )
     email = EmailField(
         _('Email'),
         validators=[

programming_language: Python
filename: page_pref_general.py
change_type: ModificationType.MODIFY
diff: @@ -25,7 +25,7 @@ import re
 import cherrypy
 from wtforms.fields import HiddenField, PasswordField, StringField, SubmitField
 from wtforms.fields.html5 import EmailField
-from wtforms.validators import DataRequired, EqualTo, InputRequired, Length, Regexp
+from wtforms.validators import DataRequired, EqualTo, InputRequired, Length, Optional, Regexp
 
 from rdiffweb.controller import Controller, flash
 from rdiffweb.controller.form import CherryForm
@@ -40,7 +40,13 @@ PATTERN_EMAIL = re.compile(r'[a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,4}$')
 class UserProfileForm(CherryForm):
     action = HiddenField(default='set_profile_info')
     username = StringField(_('Username'), render_kw={'readonly': True})
-    fullname = StringField(_('Fullname'))
+    fullname = StringField(
+        _('Fullname'),
+        validators=[
+            Optional(),
+            Length(max=256, message=_('Fullname too long.')),
+        ],
+    )
     email = EmailField(
         _('Email'),
         validators=[

programming_language: Python
filename: page_pref_tokens.py
change_type: ModificationType.MODIFY
diff: @@ -20,7 +20,7 @@ import logging
 
 import cherrypy
 from wtforms.fields import DateField, HiddenField, StringField, SubmitField
-from wtforms.validators import DataRequired, Optional
+from wtforms.validators import DataRequired, Length, Optional
 
 from rdiffweb.controller import Controller, flash
 from rdiffweb.controller.filter_authorization import is_maintainer
@@ -38,7 +38,10 @@ class TokenForm(CherryForm):
         description=_(
             'Used only to identify the purpose of the token. For example, the application that uses the token.'
         ),
-        validators=[DataRequired()],
+        validators=[
+            DataRequired(),
+            Length(max=256, message=_('Token name too long')),
+        ],
     )
     expiration = DateField(
         _('Expiration date'),

programming_language: Python
filename: test_page_admin_users.py
change_type: ModificationType.MODIFY
diff: @@ -58,7 +58,7 @@ class AbstractAdminTest(rdiffweb.test.WebCase):
     def _load_quota(self, userobj):
         return self._quota.get(userobj.username, 0)
 
-    def _add_user(self, username=None, email=None, password=None, user_root=None, role=None, mfa=None):
+    def _add_user(self, username=None, email=None, password=None, user_root=None, role=None, mfa=None, fullname=None):
         b = {}
         b['action'] = 'add'
         if username is not None:
@@ -73,6 +73,8 @@ class AbstractAdminTest(rdiffweb.test.WebCase):
             b['role'] = str(role)
         if mfa is not None:
             b['mfa'] = str(mfa)
+        if fullname is not None:
+            b['fullname'] = str(fullname)
         self.getPage("/admin/users/", method='POST', body=b)
 
     def _edit_user(
@@ -275,6 +277,15 @@ class AbstractAdminTest(rdiffweb.test.WebCase):
         self.assertStatus(200)
         self.assertInBody("Root directory too long.")
 
+    def test_add_with_fullname_too_long(self):
+        # Given a too long user root
+        fullname = "fullname" * 50
+        # When trying to create the user
+        self._add_user("test2", "test@test,com", "password", "/tmp/", UserObject.USER_ROLE, fullname=fullname)
+        # Then an error is raised
+        self.assertStatus(200)
+        self.assertInBody("Fullname too long.")
+
     def test_delete_user_with_not_existing_username(self):
         """
         Verify failure to delete invalid username.

programming_language: Python
filename: test_page_prefs_general.py
change_type: ModificationType.MODIFY
diff: @@ -109,6 +109,18 @@ class PagePrefGeneralTest(rdiffweb.test.WebCase):
         user = UserObject.query.filter(UserObject.username == self.USERNAME).first()
         self.assertEqual("", user.fullname)
 
+    def test_change_fullname_too_long(self):
+        # Given an authenticated user
+        # When update the fullname
+        self._set_profile_info("test@test.com", "Fullname" * 50)
+        # Then page return with error message
+        self.assertStatus(200)
+        self.assertNotInBody("Profile updated successfully.")
+        self.assertInBody("Fullname too long.")
+        # Then database is not updated
+        user = UserObject.query.filter(UserObject.username == self.USERNAME).first()
+        self.assertEqual("", user.fullname)
+
     def test_change_email(self):
         self._set_profile_info("test@test.com")
         self.assertStatus(200)

programming_language: Python
filename: test_page_prefs_tokens.py
change_type: ModificationType.MODIFY
diff: @@ -78,6 +78,19 @@ class PagePrefTokensTest(rdiffweb.test.WebCase):
         # Then access token is not created
         self.assertEqual(0, Token.query.filter(Token.userid == userobj.userid, Token.name == 'test-token-name').count())
 
+    def test_add_access_token_with_name_too_long(self):
+        # Given an existing user
+        # When adding a new access token with name too long.
+        self.getPage(
+            "/prefs/tokens",
+            method='POST',
+            body={'action': 'add_access_token', 'name': 'token' * 52, 'expiration_time': ''},
+        )
+        # Then page return with error message
+        self.assertStatus(200)
+        # Then token name get displayed in the view
+        self.assertInBody('Token name too long')
+
     def test_delete_access_token(self):
         # Given an existing user with access_token
         userobj = UserObject.get_user(self.USERNAME)

programming_language: Python