Output encoding sandbox
One display name lands in page text, an attribute, an inline script, and a link. Pick the encoder each place needs and test it with probe values.
Goal
A profile page writes the user’s display name and website into four places: page text, a form attribute, a greeting in an inline script, and a link.
Pick an encoder for each place and test it with the probe values. A slot passes when no probe can leave it and every probe still displays exactly as the user typed it. The markup is shown as text and never rendered.
<p class="bio">Tom <3 Jerry & <b>friends</b></p>
The value leaves its slot. The parser now reads part of it as markup or code.
<input name="display" value="Tom <3 Jerry & <b>friends</b>">
The value stays in its slot and displays as typed.
<script>const greeting = 'Hello, Tom <3 Jerry & <b>friends</b>';</script>
The value stays in its slot but displays as: Tom <3 Jerry & <b>friends</b>
<a href="Tom <3 Jerry & <b>friends</b>">Website</a>
The value stays in its slot and displays as typed.
4 of 4 places still fail a probe.
Steps
01Choose an encoder for each of the four places so that no probe value can leave its slot and the website link still works.
Do this in the workbench above. This step completes itself when the condition is met.
02HTML text encoding is fine for page text. Which probe still leaves the quoted attribute when you use it there? Give the probe’s note or its value.
03Set the inline script to HTML attribute encode. The probes no longer escape, so why is it still the wrong encoder there?
04Attribute encoding keeps the link target inside its quotes. What does it not stop?
05A React or Vue template escapes {value} by default. Where can the same bug still appear?