Opened 5 weeks ago

Last modified 16 hours ago

#36017 assigned Bug

Urlize email address allows punctuation in domains

Reported by: Mike Edmunds Owned by: Gregory Mariani
Component: Utilities Version: 5.1
Severity: Normal Keywords:
Cc: Triage Stage: Accepted
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

The urlize template filter incorrectly recognizes domains in email addresses, linkifying punctuation that shouldn't be included in the address:

# Django 5.1.4, Python 3.12.4
from django.template.defaultfilters import urlize
urlize("email me@example.com,then I'll respond")
'email <a href="mailto:me@example.com,then">me@example.com,then</a> I&#x27;ll respond'
urlize("test@example?;+!.com")
'<a href="mailto:test@example?;+!.com">test@example?;+!.com</a>'

The first example should probably stop before the comma. The second example probably shouldn't linkify at all.

See also #36012.

Change History (10)

comment:1 by Sarah Boyce, 5 weeks ago

Triage Stage: UnreviewedAccepted

comment:2 by Mike Edmunds, 4 weeks ago

Possible fix: Urlizer could check that validate_email() would allow the email address before generating a mailto. That would result in it ignoring both of the examples above. (#36014 would need to be fixed first to avoid rejecting some international domains.)

comment:3 by Gregory Mariani, 4 weeks ago

Owner: set to Gregory Mariani
Status: newassigned

I have done a fix, need to run the CI to validate, first time on this repo for me:
django.utils.html.py

...
    @staticmethod
    def is_email_simple(value):
        """Return True if value looks like an email address."""
        # An @ must be in the middle of the value.
        if "@" not in value or value.startswith("@") or value.endswith("@"):
            return False
        try:
            p1, p2 = value.split("@")
        except ValueError:
            # value contains more than one @.
            return False
        # Max length for domain name labels is 63 characters per RFC 1034.
        # Helps to avoid ReDoS vectors in the domain part.
        if len(p2) > 63:
            return False
        # Dot must be in p2 (e.g. example.com)
        if "." not in p2 or p2.startswith("."):
            return False
        if not validate_email(value):
            return False
        return True
Version 0, edited 4 weeks ago by Gregory Mariani (next)

comment:4 by Gregory Mariani, 4 weeks ago

Has patch: set

comment:5 by Mike Edmunds, 4 weeks ago

Needs tests: set

comment:6 by Gregory Mariani, 4 weeks ago

Needs tests: unset

Test done and PR validated on PR #18959

Last edited 4 weeks ago by Mike Edmunds (previous) (diff)

comment:7 by Gregory Mariani, 24 hours ago

Triage Stage: AcceptedReady for checkin

comment:8 by Sarah Boyce, 22 hours ago

Triage Stage: Ready for checkinAccepted

comment:9 by Sarah Boyce, 22 hours ago

Patch needs improvement: set

comment:10 by Gregory Mariani, 16 hours ago

Patch needs improvement: unset

@Sarah Boyce who change the triage if someone has already done a review on the PR ?

Note: See TracTickets for help on using tickets.
Back to Top