Django Template - Пометить только определенные HTML-теги как безопасные

У меня есть следующий сценарий использования: пользователь должен иметь возможность вводить HTML ввод и он должен отображаться как таковой. Однако он может содержать только теги <br>, <italic>, <strong>, <ul> or <li>.

Я знаю о безопасном фильтре, но тогда он будет разрешать каждый HTML-ввод и будет подвержен XSS.

Есть идеи, как я могу решить эту проблему?

Спасибо!

Мы можем сделать валидатор, который разрешает только определенные теги, например, с BeautifulSoup:

from bs4 import BeautifulSoup
from bs4.element import Tag
from django.core.exceptions import ValidationError
from django.utils.deconstruct import deconstructible


@deconstructible
class HtmlValidator:
    def __init__(self, tags=()):
        self.tags = tags

    def validate(self, node):
        if isinstance(node, Tag):
            if node.name not in self.tags:
                raise ValidationError(f'Tag {node.name} is not a valid tag')
            for child in node:
                self.validate(child)

    def __call__(self, value):
        soup = BeautifulSoup(value, 'html.parser')
        for child in soup:
            self.validate(soup)

Тогда мы можем добавить такой валидатор в модель:

class MyModel(models.Model):
    content = models.CharField(
        max_length=1024,
        validators=[HtmlValidator(tags={'br', 'italic', 'strong', 'ul', 'li'})],
    )
    # …

Как упоминалось в ответе на этот вопрос, можно использовать bleach.

Начните с определения списка тегов, которые вы хотите разрешить, переопределив стандартные ALLOWED_TAGS

ALLOWED_TAGS = ['br', 'italic', 'strong', 'ul', 'li']

Затем, используйте bleach.clean() для удаления любых других HTML тегов, которые не разрешены

user_input = '<p>an <strong>example</strong> for SO</p>'
cleaned_user_input = bleach.clean(user_input, tags=ALLOWED_TAGS)

Это удалит тег p из тега user_input.

Вернуться на верх