from xml.sax.saxutils import quoteattr
class SafeHTMLMixin(object):
def sanitize(self, s):
"""sanitize value following
https://www.owasp.org/index.php/XSS_%28Cross_Site_Scripting%29_Prevention_Cheat_Sheet#RULE_.231_-_HTML_Escape_Before_Inserting_Untrusted_Data_into_HTML_Element_Content
"""
if isinstance(s, (list, tuple)):
return tuple(self.sanitize(x) for x in s)
elif not isinstance(s, SafeHTMLMixin):
return quoteattr(
s,
entities={'"': '"', '/': '/', "'": '''})[1:-1]
else:
return s
def __add__(self, s):
return self.__class__(super(SafeHTMLMixin, self).__add__(self.sanitize(s)))
def __radd__(self, s):
return self.__class__(self.sanitize(s)) + self
def __mul__(self, i):
return self.__class__(super(SafeHTMLMixin, self).__mul__(i))
def __rmul__(self, i):
return self.__class__(super(SafeHTMLMixin, self).__rmul__(i))
def __mod__(self, s):
return self.__class__(super(SafeHTMLMixin, self).__mod__(self.sanitize(s)))
def __repr__(self):
return '%s(%s)' % (self.__class__.__name__,
super(SafeHTMLMixin, self).__repr__())
class SafeHTMLStr(SafeHTMLMixin, str):
"""a string that will sanitize all str concatenated to it (or inserted
via format)
SafeHTMLStr itself is not quoted::
>>> SafeHTMLStr('') + SafeHTMLStr('