HackBlue

Labs / Web and API security

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.

  • Interactive lab
  • Intermediate
  • 5 steps
  • 0 of 5 solved

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.

Probe valueAngle brackets and an ampersand
Page textfails a probe
<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.

Quoted attributefails a probe
<input name="display" value="Tom &lt;3 Jerry &amp; &lt;b&gt;friends&lt;/b&gt;">

The value stays in its slot and displays as typed.

Inline script stringfails a probe
<script>const greeting = 'Hello, Tom &lt;3 Jerry &amp; &lt;b&gt;friends&lt;/b&gt;';</script>

The value stays in its slot but displays as: Tom &lt;3 Jerry &amp; &lt;b&gt;friends&lt;/b&gt;

Link targetfails a probe
<a href="Tom &lt;3 Jerry &amp; &lt;b&gt;friends&lt;/b&gt;">Website</a>

The value stays in its slot and displays as typed.

4 of 4 places still fail a probe.

Steps

  1. 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.

  2. 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.

  3. 03Set the inline script to HTML attribute encode. The probes no longer escape, so why is it still the wrong encoder there?

  4. 04Attribute encoding keeps the link target inside its quotes. What does it not stop?

  5. 05A React or Vue template escapes {value} by default. Where can the same bug still appear?