VYPR
High severityNVD Advisory· Published Dec 23, 2022· Updated Apr 9, 2025

Open Redirect in ikus060/rdiffweb

CVE-2022-4720

Description

Open Redirect in GitHub repository ikus060/rdiffweb prior to 2.5.5.

AI Insight

LLM-synthesized narrative grounded in this CVE's description and references.

Open redirect in rdiffweb prior to 2.5.5 allows attackers to craft malicious links in email notifications, enabling phishing attacks.

Vulnerability

Overview

CVE-2022-4720 is an open redirect vulnerability in rdiffweb, a web-based backup management tool, affecting versions prior to 2.5.5. The root cause lies in the email notification templates, which automatically converted plain text into hyperlinks. This allowed an attacker to inject a malicious URL that would be rendered as a clickable link in emails sent to users [2].

Exploitation

An attacker with the ability to influence data included in email notifications—such as repository names—could craft a string that, when processed by the template, becomes a hyperlink pointing to an external site. No special privileges are required beyond the ability to create or modify repositories that trigger notifications. The attack surface is the email notification system, which sends alerts about backup status [1].

Impact

Successful exploitation enables an attacker to perform open redirect attacks, leading users to malicious websites. This can be leveraged for phishing campaigns, potentially resulting in credential theft or malware installation. The vulnerability is classified as an open redirect with moderate severity [3][4].

Mitigation

The issue is fixed in rdiffweb version 2.5.5. The commit [2] disables automatic hyperlink generation in email templates by wrapping text in ` tags without an href` attribute, preventing unintended redirects. Users are advised to upgrade to the latest version. No workarounds are documented.

AI Insight generated on May 20, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
rdiffwebPyPI
< 2.5.52.5.5

Affected products

2
  • ghsa-coords
    Range: < 2.5.5
  • ikus060/ikus060/rdiffwebv5
    Range: unspecified

Patches

1
6afaae56a295

Disable automatic hyperlink in email template

https://github.com/ikus060/rdiffwebPatrik DufresneDec 21, 2022via ghsa
9 files changed · +45 28
  • rdiffweb/core/notification.py+2 2 modified
    @@ -73,7 +73,7 @@ def access_token_added(self, userobj, name):
     
             # Send a mail notification
             body = self.app.templates.compile_template(
    -            "access_token_added.html", **{"header_name": self.app.cfg.header_name, 'user': userobj, 'name': name}
    +            "email_access_token_added.html", **{"header_name": self.app.cfg.header_name, 'user': userobj, 'name': name}
             )
             self.bus.publish('queue_mail', to=userobj.email, subject=_("A new access token has been created"), message=body)
     
    @@ -118,7 +118,7 @@ def user_password_changed(self, userobj):
     
             # If the email attributes was changed, send a mail notification.
             body = self.app.templates.compile_template(
    -            "password_changed.html", **{"header_name": self.app.cfg.header_name, 'user': userobj}
    +            "email_password_changed.html", **{"header_name": self.app.cfg.header_name, 'user': userobj}
             )
             self.bus.publish('queue_mail', to=userobj.email, subject=_("Password changed"), message=body)
     
    
  • rdiffweb/core/tests/test_notification.py+5 5 modified
    @@ -64,7 +64,7 @@ def test_notification_job(self):
             self.listener.queue_email.assert_called_once_with(
                 to='test@test.com',
                 subject='Notification',
    -            message="<html>\n  <head></head>\n  <body>\n    Hey admin,\n    <p>\n      You are receiving this email to notify you about your backups. The\n      following repositories are inactive for some time. We invite you to have a look\n      at your last backup schedule.\n    </p>\n    <ul>\n      <li>testcases</li>\n    </ul>\n    <p>\n      If you don't want to be notify about this. You need to review your\n      user preferences.\n    </p>\n  </body>\n</html>",
    +            message="<html>\n  <head></head>\n  <body>\n    <p>\n      <a>Hey admin,</a>\n    </p>\n    <p>\n      You are receiving this email to notify you about your backups. The\n      following repositories are inactive for some time. We invite you to have a look\n      at your last backup schedule.\n    </p>\n    <ul>\n      \n        <li>\n          <a>testcases</a>\n        </li>\n      \n    </ul>\n    <p>If you don't want to be notify about this. You need to review your user preferences.</p>\n  </body>\n</html>",
             )
     
         def test_notification_job_undefined_last_backup_date(self):
    @@ -85,7 +85,7 @@ def test_notification_job_undefined_last_backup_date(self):
             self.listener.queue_email.assert_called_once_with(
                 to='test@test.com',
                 subject='Notification',
    -            message="<html>\n  <head></head>\n  <body>\n    Hey admin,\n    <p>\n      You are receiving this email to notify you about your backups. The\n      following repositories are inactive for some time. We invite you to have a look\n      at your last backup schedule.\n    </p>\n    <ul>\n      <li>broker-repo</li>\n    </ul>\n    <p>\n      If you don't want to be notify about this. You need to review your\n      user preferences.\n    </p>\n  </body>\n</html>",
    +            message="<html>\n  <head></head>\n  <body>\n    <p>\n      <a>Hey admin,</a>\n    </p>\n    <p>\n      You are receiving this email to notify you about your backups. The\n      following repositories are inactive for some time. We invite you to have a look\n      at your last backup schedule.\n    </p>\n    <ul>\n      \n        <li>\n          <a>broker-repo</a>\n        </li>\n      \n    </ul>\n    <p>If you don't want to be notify about this. You need to review your user preferences.</p>\n  </body>\n</html>",
             )
     
         def test_notification_job_without_notification(self):
    @@ -135,7 +135,7 @@ def test_email_changed(self):
             self.listener.queue_email.assert_called_once_with(
                 to='original_email@test.com',
                 subject='Email address changed',
    -            message='<html>\n  <head></head>\n  <body>\n    Hey admin,\n    <p>You recently changed the email address 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>',
    +            message='<html>\n  <head></head>\n  <body>\n    <p>\n      <a>Hey admin,</a>\n    </p>\n    <p>\n      <a>You recently changed the email address associated with your Rdiffweb 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>',
             )
     
         def test_email_updated_with_same_value(self):
    @@ -167,7 +167,7 @@ def test_password_change_notification(self):
             self.listener.queue_email.assert_called_once_with(
                 to='password_change@test.com',
                 subject='Password changed',
    -            message='<html>\n  <head></head>\n  <body>\n    Hey admin,\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>',
    +            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_password_change_with_same_value(self):
    @@ -186,5 +186,5 @@ def test_password_change_with_same_value(self):
             self.listener.queue_email.assert_called_once_with(
                 to='password_change@test.com',
                 subject='Password changed',
    -            message='<html>\n  <head></head>\n  <body>\n    Hey admin,\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>',
    +            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>',
             )
    
  • rdiffweb/templates/access_token_added.html+0 10 removed
    @@ -1,10 +0,0 @@
    -<html>
    -  <head></head>
    -  <body>
    -    {% trans username=user.username %}Hey {{ username }},{% endtrans %}
    -    <p>{% trans %}A new access token, named "{{ name }}", has been created.{% endtrans %}</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>
    
  • rdiffweb/templates/email_access_token_added.html+14 0 added
    @@ -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 access token, named "{{ name }}", has been created.{% 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>
    
  • rdiffweb/templates/email_changed.html+6 2 modified
    @@ -1,8 +1,12 @@
     <html>
       <head></head>
       <body>
    -    {% trans username=(user.fullname or user.username) %}Hey {{ username }},{% endtrans %}
    -    <p>{% trans %}You recently changed the email address associated with your {{ header_name }} account.{% endtrans %}</p>
    +    <p>
    +      <a>{% trans username=(user.fullname or user.username) %}Hey {{ username }},{% endtrans %}</a>
    +    </p>
    +    <p>
    +      <a>{% trans %}You recently changed the email address associated with your {{ header_name }} 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>
    
  • rdiffweb/templates/email_mfa.html+3 1 modified
    @@ -1,7 +1,9 @@
     <html>
       <head></head>
       <body>
    -    {% trans username=(user.fullname or user.username) %}Hey {{ username }},{% endtrans %}
    +    <p>
    +      <a>{% trans username=(user.fullname or user.username) %}Hey {{ username }},{% endtrans %}</a>
    +    </p>
         <p>
           {% if user.mfa %}
             {% trans %}Your {{ header_name }} Account is now protected with Two-Factor Authentication. When you sign in on a new or untrusted device, you'll need your second factor to verify your identity.{% endtrans %}
    
  • rdiffweb/templates/email_notification.html+9 6 modified
    @@ -1,18 +1,21 @@
     <html>
       <head></head>
       <body>
    -    {% trans username=(user.fullname or user.username) %}Hey {{ username }},{% endtrans %}
    +    <p>
    +      <a>{% trans username=(user.fullname or user.username) %}Hey {{ username }},{% endtrans %}</a>
    +    </p>
         <p>
           {% trans %}You are receiving this email to notify you about your backups. The
           following repositories are inactive for some time. We invite you to have a look
           at your last backup schedule.{% endtrans %}
         </p>
         <ul>
    -      {% for r in repos %}<li>{{ r.display_name }}</li>{% endfor %}
    +      {% for r in repos %}
    +        <li>
    +          <a>{{ r.display_name }}</a>
    +        </li>
    +      {% endfor %}
         </ul>
    -    <p>
    -      {% trans %}If you don't want to be notify about this. You need to review your
    -      user preferences.{% endtrans %}
    -    </p>
    +    <p>{% trans %}If you don't want to be notify about this. You need to review your user preferences.{% endtrans %}</p>
       </body>
     </html>
    
  • rdiffweb/templates/email_password_changed.html+3 1 renamed
    @@ -1,7 +1,9 @@
     <html>
       <head></head>
       <body>
    -    {% trans username=user.username %}Hey {{ username }},{% endtrans %}
    +    <p>
    +      <a>{% trans username=(user.fullname or user.username) %}Hey {{ username }},{% endtrans %}</a>
    +    </p>
         <p>{% trans %}You recently changed the password associated with your {{ header_name }} account.{% endtrans %}</p>
         <p>
           {% trans %}If you did not make this change and believe your account has been compromised, please contact your administrator.{% endtrans %}
    
  • rdiffweb/templates/email_verification_code.html+3 1 modified
    @@ -1,7 +1,9 @@
     <html>
       <head></head>
       <body>
    -    {% trans username=(user.fullname or user.username) %}Hey {{ username }},{% endtrans %}
    +    <p>
    +      <a>{% trans username=(user.fullname or user.username) %}Hey {{ username }},{% endtrans %}</a>
    +    </p>
         <p>
           {% trans %}To help us make sure it's really you, here's the verification code you'll need to log in:{% endtrans %}
         </p>
    

Vulnerability mechanics

Generated on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

5

News mentions

0

No linked articles in our index yet.