Sanitization and Security¶
Server-side Sanitization¶
The recommended approach for sanitization is to use the extensions mechanism with the sanitize=True parameter. This automatically generates appropriate sanitization rules for nh3 based on your specific extension configuration:
# Enable sanitization based on extension configuration
content = ProseEditorField(
extensions={"Bold": True, "Link": True},
sanitize=True
)
This ensures that the sanitization ruleset precisely matches your enabled extensions, providing strict security with minimal impact on legitimate content.
How Sanitization Works with Extensions¶
When you enable extensions, the sanitization system automatically generates rules that match your configuration. For example:
content = ProseEditorField(
extensions={
"Link": {
"protocols": ["http", "https", "mailto"], # Only allow these protocols
}
},
sanitize=True
)
This will automatically restrict URLs during sanitization to only the specified protocols, removing any links with other protocols like javascript: or data:.
Accessing Sanitization Rules Directly¶
You can also access the generated sanitization rules directly:
from django_prose_editor.config import allowlist_from_extensions
allowlist = allowlist_from_extensions(extensions={"Bold": True, "Link": True})
# Returns {"tags": ["strong", "a"], "attributes": {"a": ["href", "title", "rel", "target"]}}
Creating Custom Sanitizers¶
You can create a custom sanitizer function from any extension configuration using the create_sanitizer utility:
from django_prose_editor.fields import create_sanitizer
# Create a sanitizer function for a specific set of extensions
my_sanitizer = create_sanitizer({
"Bold": True,
"Italic": True,
"Link": {"enableTarget": True}
})
# Use the sanitizer in your code
sanitized_html = my_sanitizer(unsafe_html)
This is particularly useful when you need a standalone sanitizer that matches your editor configuration without using the entire field.
Extension-to-HTML Mapping¶
This table shows how editor extensions map to HTML elements and attributes:
Extension |
HTML Elements |
HTML Attributes |
|---|---|---|
Bold |
<strong> |
|
Italic |
<em> |
|
Strike |
<s> |
|
Underline |
<u> |
|
Subscript |
<sub> |
|
Superscript |
<sup> |
|
Heading |
<h1> to <h6> |
|
BulletList |
<ul> |
|
OrderedList |
<ol> |
start, type |
ListItem |
<li> |
|
Blockquote |
<blockquote> |
|
HorizontalRule |
<hr> |
|
Link |
<a> |
href, title, target, rel |
Table |
<table>, <tr>, <th>, <td> |
rowspan, colspan |
Custom Sanitization¶
You can also pass your own callable receiving and returning HTML
using the sanitize keyword argument if you need custom sanitization logic:
def my_custom_sanitizer(html):
# Your custom sanitization logic here
return cleaned_html
content = ProseEditorField(
extensions={"Bold": True, "Link": True},
sanitize=my_custom_sanitizer
)
Note that when using a custom sanitizer, you’re responsible for ensuring that the sanitization rules match your enabled extensions.
Security Best Practices¶
Always use sanitization: Enable
sanitize=Trueor provide a custom sanitizerMatch extensions to sanitization: Use the extension-based sanitization to ensure consistency between what the editor allows and what gets sanitized
Restrict protocols: When using Link extensions, limit protocols to trusted schemes (http, https, mailto)
Validate on the server: Never trust client-side validation alone - always sanitize on the server side
Regular updates: Keep nh3 and django-prose-editor updated for security patches
Test your configuration: Verify that your sanitization rules work as expected with your specific extension configuration