Bij het ontwikkelen van webapplicaties is het zeer riskant om gebruikersinvoer direct op HTML-pagina's weer te geven. Dit opent de deur naar XSS (Cross-Site Scripting) aanvallen. Kwaadwillende gebruikers kunnen gegevens indienen die <script> tags bevatten, en als deze gegevens ongewijzigd in de browser van een andere gebruiker worden weergegeven, kan de sessiecookie worden gestolen of kan malafide code worden uitgevoerd.
Django biedt krachtige tools in de vorm van django.utils.html om deze beveiligingsdreigingen te blokkeren en HTML veilig te verwerken. 🛡️
1. De Sleutel tot XSS Bescherming: escape()
Dit is de meest fundamentele en essentiële functie van deze module. escape() zet bepaalde HTML speciale tekens in een string om in HTML-entiteiten, zodat de browser deze als gewone tekst en niet als tags herkent.
<wordt<>wordt>'(enkeltje) wordt'"(dubbele aanhalingstekens) wordt"&wordt&
Voorbeeld:
from django.utils.html import escape
# Kwaadwillige gebruikersinvoer
malicious_input = "<script>alert('XSS Attack!');</script>"
# escape verwerking
safe_output = escape(malicious_input)
print(safe_output)
# Resultaat:
# <script>alert('XSS Attack!');</script>
Deze omgezette string wordt niet als script uitgevoerd in de browser, maar verschijnt als tekst <script>alert('XSS Attack!');</script>.
[Belangrijk] Automatische Escape van Django Templates
Gelukkig behandelt de Django template-engine standaard alle variabelen automatisch met escape.
{{ user_input }}
Daarom wordt de escape() functie voornamelijk gebruikt wanneer HTML handmatig buiten de templates moet worden verwerkt (bijvoorbeeld in weergavelogica of bij het genereren van API-responses).
2. Alle HTML-tags Verwijderen: strip_tags()
Soms wil je verder gaan dan het escapen van HTML en alle tags verwijderen om alleen platte tekst te extraheren. Bijvoorbeeld, wanneer je alle HTML-tags uit de bloginhoud wilt verwijderen en deze wilt gebruiken als samenvatting van de zoekresultaten.
strip_tags() doet precies dit.
Voorbeeld:
from django.utils.html import strip_tags
html_content = "<p>Dit is een <strong>zeer belangrijke</strong> <em>mededeling</em>.</p>"
plain_text = strip_tags(html_content)
print(plain_text)
# Resultaat:
# Dit is een zeer belangrijke mededeling.
# (Spaties tussen de tags worden ook netjes opgeruimd)
3. Veilig HTML Genereren: format_html()
Een van de meest krachtige en belangrijke functies.
Soms moet je dynamisch HTML genereren in Python-code (bijvoorbeeld in views.py of models.py). Bijvoorbeeld, wanneer een methode van een model een link in een bepaalde indeling moet retourneren voor de beheerderspagina.
Als je strings samenvoegt met Python's f-string of de + operator, is dit zeer kwetsbaar voor XSS-aanvallen.
format_html(format_string, *args, **kwargs) verwerkt automatisch alle argumenten (args, kwargs) met escape() en voegt ze in de string in. Het eindresultaat wordt gemarkeerd als "deze HTML is veilig" (mark_safe), zodat het in de template niet ge-escaped wordt en zonder wijzigingen gerenderd wordt.
Voorbeeld: (Link genereren voor de beheerderspagina vanuit een modelmethode)
from django.db import models
from django.utils.html import format_html
from django.utils.text import slugify
class Post(models.Model):
title = models.CharField(max_length=100)
def get_edit_link(self):
# [Slechte Voorbeeld] f-string: als self.title
댓글이 없습니다.