CVE-2022-4638: Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting') (CWE-79)
value: A vulnerability classified as problematic was found in collective.contact.widget up to 1.12. This vulnerability affects the function title of the file src/collective/contact/widget/widgets.py. The manipulation leads to cross site scripting. The attack can be initiated remotely. The name of the patch is 5da36305ca7ed433782be8901c47387406fcda12. It is recommended to apply a patch to fix this issue. The identifier of this vulnerability is VDB-216496.
CWE description: The product does not neutralize or incorrectly neutralizes user-controllable input before it is placed in output that is used as a web page that is served to other users.
CVSS v3 base score: 6.1
Published: 2022-12-21T22:15Z
Repository: https://github.com/collective/collective.contact.widget
Language: Python
Files changed: CHANGES.rst, src/collective/contact/widget/widgets.py
Commit date: 2022-05-31 23:16:59 +0200
Commit message: Escaped term-contact viewlet title special chars to avoid xss

Diff: diff --git a/CHANGES.rst b/CHANGES.rst
index 67f9f3f..8f18674 100644
--- a/CHANGES.rst
+++ b/CHANGES.rst
@@ -2,12 +2,14 @@ Changelog
 =========
 
 1.13 (unreleased)
 -----------------
 
-- Nothing changed yet.
-
+- Escaped contact title special characters in `term-contact` viewlet to avoid
+  script insertion (xss). This viewlet stores an hidden field used in a
+  dynamically js generation.
+  [sgeulette]
 
 1.12 (2020-10-07)
 -----------------
 
 - Added prefiltering on widgets
diff --git a/src/collective/contact/widget/widgets.py b/src/collective/contact/widget/widgets.py
index bca771f..d897dbc 100644
--- a/src/collective/contact/widget/widgets.py
+++ b/src/collective/contact/widget/widgets.py
@@ -1,49 +1,49 @@
-import json
-
+from cgi import escape
+from collective.contact.widget import _
+from collective.contact.widget.interfaces import IContactAutocompleteMultiSelectionWidget
+from collective.contact.widget.interfaces import IContactAutocompleteSelectionWidget
+from collective.contact.widget.interfaces import IContactAutocompleteWidget
+from collective.contact.widget.interfaces import IContactContent
+from collective.contact.widget.interfaces import IContactWidgetSettings
+from five import grok
+from plone.app.layout.viewlets.interfaces import IBelowContent
+from plone.app.layout.viewlets.interfaces import IHtmlHeadLinks
+from plone.formwidget.autocomplete.widget import AutocompleteMultiSelectionWidget
+from plone.formwidget.autocomplete.widget import AutocompleteSearch as BaseAutocompleteSearch
+from plone.formwidget.autocomplete.widget import AutocompleteSelectionWidget
+from Products.CMFPlone.utils import base_hasattr
+from Products.CMFPlone.utils import safe_unicode
 from z3c.form.interfaces import IFieldWidget
-import z3c.form.interfaces
 from z3c.form.widget import FieldWidget
+from zope.browserpage.viewpagetemplatefile import ViewPageTemplateFile
 from zope.component import getUtility
 from zope.component.interfaces import ComponentLookupError
 from zope.i18n import translate
-from zope.interface import implementer, implements, Interface
-from zope.browserpage.viewpagetemplatefile import ViewPageTemplateFile
+from zope.interface import implementer
+from zope.interface import implements
+from zope.interface import Interface
 from zope.schema.interfaces import IContextSourceBinder
 from zope.schema.interfaces import IVocabulary
 from zope.schema.interfaces import IVocabularyFactory
-from five import grok
 
-from Products.CMFPlone.utils import base_hasattr, safe_unicode
-from plone.app.layout.viewlets.interfaces import IBelowContent
-from plone.app.layout.viewlets.interfaces import IHtmlHeadLinks
-from plone.formwidget.autocomplete.widget import (
-    AutocompleteMultiSelectionWidget,
-    AutocompleteSelectionWidget)
-from plone.formwidget.autocomplete.widget import AutocompleteSearch as BaseAutocompleteSearch
+import json
+import z3c.form.interfaces
+
 
 try:
-    from plone.formwidget.masterselect.widget import MasterSelect as BaseMasterSelect
     from plone.formwidget.masterselect.interfaces import IMasterSelectWidget
+    from plone.formwidget.masterselect.widget import MasterSelect as BaseMasterSelect
     class MasterSelect(BaseMasterSelect):
         grok.implements(IMasterSelectWidget)
         def getSlaves(self):
             for slave in self.field.slave_fields:
                 yield slave.copy()
 except ImportError:
     class MasterSelect(object):
         pass
 
-from collective.contact.widget import _
-from collective.contact.widget.interfaces import (
-    IContactAutocompleteWidget,
-    IContactAutocompleteSelectionWidget,
-    IContactAutocompleteMultiSelectionWidget,
-    IContactContent,
-    IContactWidgetSettings,
-)
-
 
 class PatchLoadInsideOverlay(grok.Viewlet):
     grok.context(Interface)
     grok.viewletmanager(IHtmlHeadLinks)
     wait_msg = _(u"please wait")
@@ -68,11 +68,11 @@ class TermViewlet(grok.Viewlet):
         if base_hasattr(self.context, 'get_full_title'):
             title = self.context.get_full_title()
         else:
             title = self.context.Title()
         title = title and safe_unicode(title) or u""
-        return title
+        return escape(title, quote=True)
 
     @property
     def portal_type(self):
         return self.context.portal_type
 

Vulnerable code: - Nothing changed yet.

import json

import z3c.form.interfaces
from zope.interface import implementer, implements, Interface
from zope.browserpage.viewpagetemplatefile import ViewPageTemplateFile
from five import grok
from Products.CMFPlone.utils import base_hasattr, safe_unicode
from plone.app.layout.viewlets.interfaces import IBelowContent
from plone.app.layout.viewlets.interfaces import IHtmlHeadLinks
from plone.formwidget.autocomplete.widget import (
    AutocompleteMultiSelectionWidget,
    AutocompleteSelectionWidget)
from plone.formwidget.autocomplete.widget import AutocompleteSearch as BaseAutocompleteSearch
    from plone.formwidget.masterselect.widget import MasterSelect as BaseMasterSelect
from collective.contact.widget import _
from collective.contact.widget.interfaces import (
    IContactAutocompleteWidget,
    IContactAutocompleteSelectionWidget,
    IContactAutocompleteMultiSelectionWidget,
    IContactContent,
    IContactWidgetSettings,
)

        return title
Fixed code: - Escaped contact title special characters in `term-contact` viewlet to avoid
  script insertion (xss). This viewlet stores an hidden field used in a
  dynamically js generation.
  [sgeulette]
from cgi import escape
from collective.contact.widget import _
from collective.contact.widget.interfaces import IContactAutocompleteMultiSelectionWidget
from collective.contact.widget.interfaces import IContactAutocompleteSelectionWidget
from collective.contact.widget.interfaces import IContactAutocompleteWidget
from collective.contact.widget.interfaces import IContactContent
from collective.contact.widget.interfaces import IContactWidgetSettings
from five import grok
from plone.app.layout.viewlets.interfaces import IBelowContent
from plone.app.layout.viewlets.interfaces import IHtmlHeadLinks
from plone.formwidget.autocomplete.widget import AutocompleteMultiSelectionWidget
from plone.formwidget.autocomplete.widget import AutocompleteSearch as BaseAutocompleteSearch
from plone.formwidget.autocomplete.widget import AutocompleteSelectionWidget
from Products.CMFPlone.utils import base_hasattr
from Products.CMFPlone.utils import safe_unicode
from zope.browserpage.viewpagetemplatefile import ViewPageTemplateFile
from zope.interface import implementer
from zope.interface import implements
from zope.interface import Interface
import json
import z3c.form.interfaces

    from plone.formwidget.masterselect.widget import MasterSelect as BaseMasterSelect
        return escape(title, quote=True)