Reputation: 7279
I have the following use case: a user should be able to enter in HTML input and it should be displayed as such. However, it can only contain <br>, <italic>, <strong>, <ul> or <li>
tags.
I know about the safe filter, but that way it would allow every HTML input and be prone to XSS.
Any idea how I can solve this?
Thanks!
Upvotes: 2
Views: 772
Reputation: 13582
As mentioned in the answer to this question, one can use bleach
.
Start by defining a list of the tags one wants to allow by overriding the default ALLOWED_TAGS
ALLOWED_TAGS = ['br', 'italic', 'strong', 'ul', 'li']
Then, use bleach.clean()
to remove any other HTML tags that are not allowed
user_input = '<p>an <strong>example</strong> for SO</p>'
cleaned_user_input = bleach.clean(user_input, tags=ALLOWED_TAGS)
This will remove the p
tag from the user_input
.
Upvotes: 1
Reputation: 476493
We can make a validator that only allows certain tags, for example with 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)
Then we can add such validator to the model:
class MyModel(models.Model):
content = models.CharField(
max_length=1024,
validators=[HtmlValidator(tags={'br', 'italic', 'strong', 'ul', 'li'})],
)
# …
Upvotes: 0