-
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #2 from plone-security/folder-contents-escape-or-h…
…tml-safe Folder contents: escape or html safe
- Loading branch information
Showing
8 changed files
with
281 additions
and
67 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
# -*- coding: utf-8 -*- | ||
from ._compat import char_types | ||
from .htmltools import html_escape | ||
from .htmltools import html_safe | ||
|
||
import json | ||
|
||
try: | ||
# plone.app.content 3 | ||
from plone.app.content.browser import contents as fc | ||
except ImportError: | ||
try: | ||
# 2.2.x | ||
from plone.app.content.browser import folder as fc | ||
except ImportError: | ||
# 2.1.x and lower do not need this patch | ||
fc = None | ||
|
||
|
||
if fc is not None: | ||
# Patch ContextInfo | ||
# If PloneHotfix20200121 is loaded, then the original call will already | ||
# have been saved under a different name. | ||
# We patch that one, instead of letting our patch call a patch which calls the original. | ||
orig_name = "_orig___call__" | ||
if not hasattr(fc.ContextInfo, orig_name): | ||
setattr(fc.ContextInfo, orig_name, fc.ContextInfo.__call__) | ||
|
||
def context_info_call(self): | ||
result = self._orig___call__() | ||
data = json.loads(result) | ||
obj = data.get("object", None) | ||
if obj is None: | ||
return result | ||
changed = False | ||
for key, value in obj.items(): | ||
if not isinstance(value, char_types): | ||
continue | ||
safe_value = html_safe(value) | ||
if safe_value == value: | ||
continue | ||
obj[key] = safe_value | ||
changed = True | ||
if not changed: | ||
return result | ||
result = json.dumps(data) | ||
return result | ||
|
||
|
||
fc.ContextInfo.__call__ = context_info_call |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
from ._compat import PY2 | ||
from ._compat import text_type | ||
from Products.PortalTransforms.data import datastream | ||
from Products.PortalTransforms.transforms.safe_html import SafeHTML | ||
|
||
try: | ||
from html import escape | ||
except ImportError: | ||
from cgi import escape | ||
|
||
|
||
def safe_unicode(value): | ||
# This is like Products.CMFPlone.utils.safe_unicode, but in this case we always | ||
# ruturn unicode, also when we get an integer as input. | ||
if isinstance(value, text_type): | ||
return value | ||
try: | ||
value = text_type(value) | ||
except UnicodeDecodeError: | ||
value = value.decode('utf-8', 'replace') | ||
return value | ||
|
||
|
||
def safe_utf8(value): | ||
return safe_unicode(value).encode('utf-8') | ||
|
||
|
||
def scrub_html(value): | ||
# Strip illegal HTML tags from string text. | ||
transform = SafeHTML() | ||
# Available in Plone 5.2: | ||
# return transform.scrub_html(value) | ||
data = datastream("text/x-html-safe") | ||
data = transform.convert(value, data) | ||
return data.getData() | ||
|
||
|
||
# We will have two functions: | ||
# - html_escape: escape html, for example turn '<' into '<' | ||
# - html_safe: return html with dangerous tags removed, using safe html transform. | ||
# | ||
# In both Python 2 and 3, the convert function that we use in safe_html | ||
# cannot handle a non string-like value, for example an integer. | ||
# Same is true for the escape function. | ||
# Seems good to always return a string-like value though. | ||
# But should that be bytes or string or unicode? | ||
if PY2: | ||
# We use this in places where the result gets inserted in a string/bytes, | ||
# so we should use a string (utf-8) here. | ||
def html_escape(value): | ||
value = safe_utf8(value) | ||
return escape(value, 1) | ||
|
||
def html_safe(value): | ||
value = safe_utf8(value) | ||
return scrub_html(value) | ||
else: | ||
# In Python 3 this gets inserted in a string/text. | ||
def html_escape(value): | ||
value = safe_unicode(value) | ||
return escape(value, 1) | ||
|
||
def html_safe(value): | ||
value = safe_unicode(value) | ||
return scrub_html(value) |
Oops, something went wrong.