Mongoengine sanitized string field

One of the rules to prevent XSS attack is to sanitize HTML. Here is an example how to do this with Mongoengine custom field and bleach library.

import bleach
from mongoengine import Document, StringField


class Sanitizer(object):
    ALLOWED_TAGS = [
    	'table', 'thead', 'tbody', 'tfoot', 'tr', 'th', 'td',
        'div', 'p', 'a', 'span', 'blockquote', 'ul', 'ol', 'li',
        'strong', 'img', 'br', 'hr', 'h1', 'h2', 'h3', 'style'
    ]
    ALLOWED_ATTRS = {
        '*': ['id', 'style'],
        'a': ['href', 'target', 'title'],
        'img': ['src', 'alt', 'width', 'height', 'class', 'style']
    }
    ALLOWED_STYLES = [
        'color', 'background-color', 'font-size', 'font-family',
        'width', 'height', 'border', 'margin', 'padding', 
        'text-decoration', 'text-align'
    ]

    @classmethod
    def sanitize(cls, content):
        return bleach.clean(
            content,
            tags=cls.ALLOWED_TAGS,
            attributes=cls.ALLOWED_ATTRS,
            styles=cls.ALLOWED_STYLES)


class SanitizedStringField(StringField):
    """
    Sanitize html when save to mongo.
    """
    def to_mongo(self, value):
        if value:
            value = Sanitizer.sanitize(value)
        value = super(SanitizedStringField, self).to_mongo(value)
        return value

class MyDocument(Document):
    html = SanitizedStringField()

Or if you want to sanitize on output from the database.

class SanitizedStringField(StringField):
    """
    Sanitize html when get from mongo.
    """

    def to_python(self, value):
        value = super(SanitizedStringField, self).to_python(value)
        if value:
            value = Sanitizer.sanitize(value)
        return value
comments powered by Disqus