Skip to content

Commit

Permalink
Fix urlize_quoted_hrefs() to make links again.
Browse files Browse the repository at this point in the history
Also now correctly escapes JSON values for the web.

fixes #5563.

(cherry picked from commit 672a623)
  • Loading branch information
ggainey committed Jul 16, 2024
1 parent b11b1ba commit 06e9e7f
Show file tree
Hide file tree
Showing 3 changed files with 66 additions and 4 deletions.
1 change: 1 addition & 0 deletions CHANGES/5563.bugfix
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Browsable HREFs now have clickable links again.
11 changes: 7 additions & 4 deletions pulpcore/app/templatetags/pulp_urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
from django import template
from django.conf import settings
from django.utils.encoding import force_str
from django.utils.html import escape
from django.utils.html import escape, smart_urlquote
from django.utils.safestring import SafeData, mark_safe

register = template.Library()
Expand All @@ -20,6 +20,8 @@
(""", """),
]
word_split_re = re.compile(r"(\s+)")
api_root_prefix = r"^" + settings.V3_API_ROOT.replace("/", r"\/")
href_re = re.compile(api_root_prefix, re.IGNORECASE)


@register.filter(needs_autoescape=True)
Expand Down Expand Up @@ -57,6 +59,9 @@ def trim_url(x, limit=trim_url_limit):
url = None
nofollow_attr = ' rel="nofollow"' if nofollow else ""

if href_re.match(middle):
url = smart_urlquote(middle)

# Check if it's a real URL
if url and ("{" in url or "%7B" in url):
url = None
Expand All @@ -74,8 +79,6 @@ def trim_url(x, limit=trim_url_limit):
words[i] = mark_safe(word)
elif autoescape:
words[i] = escape(word)
elif safe_input:
words[i] = mark_safe(word)
elif autoescape:
else:
words[i] = escape(word)
return "".join(words)
58 changes: 58 additions & 0 deletions pulpcore/tests/unit/test_pulp_urls.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import pytest
from django.conf import settings

from pulpcore.app.templatetags import pulp_urls

pytestmark = pytest.mark.usefixtures("fake_domain")


def test_urlize_quoted_hrefs_basic_url():
"""
text starts with API_ROOT, defaults. Should be made clickable
"""
txt = settings.V3_API_ROOT + "foo/bar/"
ret = pulp_urls.urlize_quoted_hrefs(txt)
assert ret == f'<a href="{txt}" rel="nofollow">{txt}</a>'


def test_urlize_quoted_hrefs_nofollow():
"""
text starts with API_ROOT, defaults. Should be made clickable
"""
txt = settings.V3_API_ROOT + "foo/bar/"
ret = pulp_urls.urlize_quoted_hrefs(txt, nofollow=False)
assert ret == f'<a href="{txt}">{txt}</a>'


def test_urlize_quoted_hrefs_trim():
"""
text starts with API_ROOT, defaults. Should be made clickable
"""
txt = settings.V3_API_ROOT + "foo/bar/"
trim_txt = txt[0] + "..."
ret = pulp_urls.urlize_quoted_hrefs(txt, trim_url_limit=4)
assert ret == f'<a href="{txt}" rel="nofollow">{trim_txt}</a>'


def test_urlize_quoted_hrefs_basic_url_xss():
"""
text starts with API_ROOT, includes XSS, defaults. Should be made clickable, escape XSS
"""
txt = settings.V3_API_ROOT + "foo/bar/<script>alert('ALERT!')</script>blech/"
escapified_linked_text = (
'<a href="' + settings.V3_API_ROOT + "foo/bar/"
'%3Cscript%3Ealert(&#x27;ALERT!&#x27;)%3C/script%3Eblech/" '
'rel="nofollow">' + settings.V3_API_ROOT + "foo/bar/&lt;script&gt;"
"alert(&#x27;ALERT!&#x27;)&lt;/script&gt;blech/</a>"
)
ret = pulp_urls.urlize_quoted_hrefs(txt)
assert ret == escapified_linked_text


def test_urlize_quoted_hrefs_basic_escape():
"""
text contains XSS. Expect escaped
"""
txt = "foo/bar/<script>alert('ALERT!')</script>blech/"
ret = pulp_urls.urlize_quoted_hrefs(txt)
assert ret == "foo/bar/&lt;script&gt;alert(&#x27;ALERT!&#x27;)&lt;/script&gt;blech/"

0 comments on commit 06e9e7f

Please sign in to comment.