CVE-2022-4719 (published 2022-12-27T15:15Z)

Business Logic Errors in GitHub repository ikus060/rdiffweb prior to 2.5.5.

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

Weakness information:
cwe_id: NVD-CWE-noinfo
cwe_name: Insufficient Information
description: There is insufficient information about the issue to classify it; details are unkown or unspecified.
extended_description: Insufficient Information

Fix information:
repo_url: https://github.com/ikus060/rdiffweb
commit_details: repo_url: https://github.com/ikus060/rdiffweb
author: Patrik Dufresne
author_date: 2022-12-22 15:54:20-05:00
msg: Send notification on new SSH Key
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: README.md
change_type: ModificationType.MODIFY
diff: @@ -108,7 +108,13 @@ Professional support for Rdiffweb is available by contacting [IKUS Soft](https:/
 
 # Changelog
 
-## Next Release - 2.5.4
+## Next Release - 2.5.5
+
+* 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)
+
+## 2.5.4 (2022-12-19)
 
 * Discard `X-Forwarded-Host` headers credit to [Anishka Shukla](https://github.com/anishkashukla)
 * Create proper symbolic link of `chartkick.js` on Ubuntu Jammy to fix loading of Charts in web interface

programming_language: Markdown
filename: _user.py
change_type: ModificationType.MODIFY
diff: @@ -182,6 +182,7 @@ class UserObject(Base):
                     _("Duplicate key. This key already exists or is associated to another user.")
                 )
         cherrypy.engine.publish('user_attr_changed', self, {'authorizedkeys': True})
+        cherrypy.engine.publish('authorizedkey_added', self, fingerprint=key.fingerprint, comment=comment)
 
     def add_access_token(self, name, expiration_time=None, length=16):
         """

programming_language: Python
filename: notification.py
change_type: ModificationType.MODIFY
diff: @@ -45,6 +45,7 @@ class NotificationPlugin(SimplePlugin):
         self.bus.log('Start Notification plugin')
         self.bus.publish('schedule_job', self.execution_time, self.notification_job)
         self.bus.subscribe('access_token_added', self.access_token_added)
+        self.bus.subscribe('authorizedkey_added', self.authorizedkey_added)
         self.bus.subscribe('user_attr_changed', self.user_attr_changed)
         self.bus.subscribe('user_password_changed', self.user_password_changed)
 
@@ -54,6 +55,7 @@ class NotificationPlugin(SimplePlugin):
         self.bus.log('Stop Notification plugin')
         self.bus.publish('unschedule_job', self.notification_job)
         self.bus.unsubscribe('access_token_added', self.access_token_added)
+        self.bus.unsubscribe('authorizedkey_added', self.authorizedkey_added)
         self.bus.unsubscribe('user_attr_changed', self.user_attr_changed)
         self.bus.unsubscribe('user_password_changed', self.user_password_changed)
 
@@ -77,6 +79,21 @@ class NotificationPlugin(SimplePlugin):
         )
         self.bus.publish('queue_mail', to=userobj.email, subject=_("A new access token has been created"), message=body)
 
+    def authorizedkey_added(self, userobj, fingerprint, comment, **kwargs):
+        if not self.send_changed:
+            return
+
+        if not userobj.email:
+            logger.info("can't sent mail to user [%s] without an email", userobj.username)
+            return
+
+        # If the email attributes was changed, send a mail notification.
+        body = self.app.templates.compile_template(
+            "email_authorizedkey_added.html",
+            **{"header_name": self.app.cfg.header_name, 'user': userobj, 'comment': comment, 'fingerprint': fingerprint}
+        )
+        self.bus.publish('queue_mail', to=userobj.email, subject=_("A new SSH Key has been added"), message=body)
+
     def user_attr_changed(self, userobj, attrs={}):
         if not self.send_changed:
             return

programming_language: Python
filename: test_notification.py
change_type: ModificationType.MODIFY
diff: @@ -188,3 +188,42 @@ class NotificationPluginTest(rdiffweb.test.WebCase):
             subject='Password changed',
             message='<html>\n  <head></head>\n  <body>\n    <p>\n      <a>Hey admin,</a>\n    </p>\n    <p>You recently changed the password associated with your Rdiffweb account.</p>\n    <p>\n      If you did not make this change and believe your account has been compromised, please contact your administrator.\n    </p>\n  </body>\n</html>',
         )
+
+    def test_access_token_added(self):
+        # Given a user with a email.
+        user = UserObject.get_user(self.USERNAME)
+        user.email = 'password_change@test.com'
+        user.set_password('new_password')
+        user.add().commit()
+        self.listener.queue_email.reset_mock()
+
+        # When adding a new access token
+        user.add_access_token('TEST')
+
+        # Then a notification is sent to the user
+        self.listener.queue_email.assert_called_once_with(
+            to='password_change@test.com',
+            subject='A new access token has been created',
+            message='<html>\n  <head></head>\n  <body>\n    <p>\n      <a>Hey admin,</a>\n    </p>\n    <p>\n      <a>A new access token, named "TEST", has been created.</a>\n    </p>\n    <p>\n      If you did not make this change and believe your account has been compromised, please contact your administrator.\n    </p>\n  </body>\n</html>',
+        )
+
+    def test_authorizedkey_added(self):
+        # Given a user with a email.
+        user = UserObject.get_user(self.USERNAME)
+        user.email = 'password_change@test.com'
+        user.set_password('new_password')
+        user.add().commit()
+        self.listener.queue_email.reset_mock()
+
+        # When adding a new access token
+        user.add_authorizedkey(
+            key="ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDSEN5VTn9MLituZvdYTZMbZEaMxe0UuU7BelxHkvxzSpVWtazrIBEc3KZjtVoK9F3+0kd26P4DzSQuPUl3yZDgyZZeXrF6p2GlEA7A3tPuOEsAQ9c0oTiDYktq5/Go8vD+XAZKLd//qmCWW1Jg4datkWchMKJzbHUgBrBH015FDbGvGDWYTfVyb8I9H+LQ0GmbTHsuTu63DhPODncMtWPuS9be/flb4EEojMIx5Vce0SNO9Eih38W7jTvNWxZb75k5yfPJxBULRnS5v/fPnDVVtD3JSGybSwKoMdsMX5iImAeNhqnvd8gBu1f0IycUQexTbJXk1rPiRcF13SjKrfXz ikus060@ikus060-t530",
+            comment="test@mysshkey",
+        )
+
+        # Then a notification is sent to the user
+        self.listener.queue_email.assert_called_once_with(
+            to='password_change@test.com',
+            subject='A new SSH Key has been added',
+            message='<html>\n  <head></head>\n  <body>\n    <p>\n      <a>Hey admin,</a>\n    </p>\n    <p>\n      <a>A new SSH Key, titled "test@mysshkey" with fingerprint "4d:42:8b:35:e5:55:71:f7:b3:0d:58:f9:b1:2c:9e:91" has been created in your account.</a>\n    </p>\n    <p>\n      If you did not make this change and believe your account has been compromised, please contact your administrator.\n    </p>\n  </body>\n</html>',
+        )

programming_language: Python
filename: email_authorizedkey_added.html
change_type: ModificationType.ADD
diff: @@ -0,0 +1,14 @@
+<html>
+  <head></head>
+  <body>
+    <p>
+      <a>{% trans username=(user.fullname or user.username) %}Hey {{ username }},{% endtrans %}</a>
+    </p>
+    <p>
+      <a>{% trans %}A new SSH Key, titled "{{ comment }}" with fingerprint "{{ fingerprint }}" has been created in your account.{% endtrans %}</a>
+    </p>
+    <p>
+      {% trans %}If you did not make this change and believe your account has been compromised, please contact your administrator.{% endtrans %}
+    </p>
+  </body>
+</html>

programming_language: HTML