diff --git a/CHANGES.rst b/CHANGES.rst
index eca3a07..44350df 100644
--- a/CHANGES.rst
+++ b/CHANGES.rst
@@ -4,8 +4,8 @@ Changelog
1.20 (unreleased)
-----------------
-- Nothing changed yet.
-
+- Escape link content to avoid malicious behaviour.
+ [gbastien]
1.19 (2022-01-12)
-----------------
diff --git a/src/imio/prettylink/adapters.py b/src/imio/prettylink/adapters.py
index 9700c5f..8904783 100644
--- a/src/imio/prettylink/adapters.py
+++ b/src/imio/prettylink/adapters.py
@@ -10,6 +10,8 @@
from Products.CMFPlone.utils import safe_unicode
from zope.i18n import translate
+import cgi
+
class PrettyLinkAdapter(object):
"""Adapter that manage rendering the pretty link."""
@@ -118,6 +120,10 @@ def _getLink(self):
icons_tag = (
icons and u"{0}".format(icons) or ""
)
+ # as link is rendered using "structure", escape various texts
+ content = cgi.escape(content)
+ title = cgi.escape(title)
+ self.target = cgi.escape(self.target)
if self.isViewable:
url = self._get_url()
css_classes = self.CSSClasses()
diff --git a/src/imio/prettylink/testing.py b/src/imio/prettylink/testing.py
index bd0821c..8f3c1d9 100644
--- a/src/imio/prettylink/testing.py
+++ b/src/imio/prettylink/testing.py
@@ -74,3 +74,4 @@ def setUp(self):
self.folder = self.portal.folder
self.folder2 = self.portal.folder2
self.catalog = self.portal.portal_catalog
+ self.maxDiff = None
diff --git a/src/imio/prettylink/tests/test_adapter.py b/src/imio/prettylink/tests/test_adapter.py
index b2463da..d604632 100644
--- a/src/imio/prettylink/tests/test_adapter.py
+++ b/src/imio/prettylink/tests/test_adapter.py
@@ -9,6 +9,7 @@
class TestPrettyLinkAdapter(IntegrationTestCase):
+
def invalidate_cache(self):
cache = getUtility(ICacheChooser)("imio.prettylink.adapters.getLink")
cache.ramcache.invalidate("imio.prettylink.adapters.getLink")
@@ -266,3 +267,20 @@ def test_getLink_link_tooltip(self):
u"Folder",
)
+
+ def test_getLink_escape_dangerous_characters(self):
+ """As link is rendered, make sure we can not embed dangerous things."""
+ self.folder.setTitle('Folder">')
+ pl = IPrettyLink(self.folder)
+ self.assertEqual(
+ pl.getLink(),
+ u'Folder"><script>alert'
+ u'(document.domain)</script>')
+ pl.tag_title = "tag_title<>"
+ pl.contentValue = "contentValue<>"
+ self.assertEqual(
+ pl.getLink(),
+ u"contentValue<>")