Ga naar hoofdinhoud

HTML van een bezoeker: tekst of HTML?

Hier bouw je op verder: F-strings

Weet je dit niet meer zeker? Lees het terug voordat je verdergaat.

Met een template blijft tekst van een bezoeker tekst; met een f-string niet. Dat zie je nu zelf, met een vet woord in het gastenboek uit les 1.

Vul HTML in​

Alleen je eigen server

Doe dit uitsluitend op je eigen server op 127.0.0.1. HTML invullen op de site van een ander om te kijken wat er gebeurt, is een aanval op die site en op de bezoekers ervan, en strafbaar.

Gooi gastenboek.db weg, zodat alleen nieuwe berichten in de lijst staan. Start je server en open http://127.0.0.1:8000/static/gastenboek.html. Vul als naam Sara in en als bericht:

<b>vet</b>

Wat de server stuurt​

De browser las wat Sara typte niet als tekst, maar als HTML. Wat de server terugstuurt, zie je met een scriptje lijst.py, in een tweede terminal:

import httpx

antwoord = httpx.get("http://127.0.0.1:8000/berichten/lijst")
print(antwoord.text)

Uitvoer:

<ul><li>Sara: <b>vet</b></li></ul>

De <b> staat er letterlijk in. Een vet woord is onschuldig, maar de browser maakt geen onderscheid: ook een <script> dat een bezoeker invult, komt zo in de pagina van iedereen die hem daarna opent, en de browser voert het uit. Dat heet XSS, cross-site scripting: code van een bezoeker die draait in de browser van een ander.

Controlevraag
Sara typte een vet woord als HTML, in haar eigen browser. Waarom is het ook vet bij een tweede bezoeker in een ander venster?
Kies wat jij denkt. Bij het goede antwoord zie je de uitleg.

Er gaat iets mis​

No module named 'httpx'​

lijst.py stopt meteen, en de foutmelding eindigt met:

ModuleNotFoundError: No module named 'httpx'

Oorzaak: het script draait met een Python buiten de virtual environment van veiligheid-xss, bijvoorbeeld in een los PowerShell-venster. Daar is httpx niet geïnstalleerd.

Oplossing: draai het script in een tweede terminal van VS Code, in de map veiligheid-xss. Staat httpx daar ook niet, installeer de packages dan zoals bij Een map per reeks.

Opdrachten​

Opdracht 1: Predict - Een schuine naam​

Een nieuwe bezoeker vult als naam <i>Noor</i> in en als bericht hoi.

Vraag: wat ziet Noor onder het formulier, direct na het versturen?

Tip

Kijk naar regel 16 van main.py in les 1: wat staat er in de f-string?

Antwoord

"Bedankt, Noor. Je bericht staat in het gastenboek.", met Noor schuin. Het antwoord na het versturen gebruikt dezelfde f-string, dus ook daar leest de browser de naam als HTML. Dat raakt alleen Noor zelf; de lijst raakt iedereen.

Opdracht 2: Investigate - En met een template?​

Het recept Verversen in het htmx-overzicht maakt de lijst met een template, berichten_lijst.html. Stel dat Sara daar <b>vet</b> invult. Wordt het dan vet?

Antwoord

Nee. Je ziet <b>vet</b> staan, met de haakjes erbij. Jinja zet in een template van elke < een &lt; en van elke > een &gt;, en die tekens toont de browser als tekst. De f-string doet dat niet. In les 3 doe je hetzelfde in Python, en in les 5 laat je het aan een template over.

Door naar les 3: escapen in Python.