·2 min read·Mounaji Studio

How to test an HTML sanitizer so the test means something

A sanitizer with green tests may be doing nothing. Three steps to test it so the suite measures what the sanitizer prevents.

securitytestinghtml

Also in: Español

If you accept HTML from an editor, your sanitizer has green tests. The question is green against what.

A test that confirms <strong> survives also passes with return html. That test doesn't measure sanitizing: it measures that legitimate markup is still there.

1. Run the suite against nothing

Two rows of 23 tests. Against a function that returns the HTML unchanged, 5 pass and 18 fail. Against the sanitizer all 23 pass.

Before running it against the sanitizer, run it against a pass-through, a function that returns the input unchanged.

In a real case, 18 of 23 tests failed. Those 18 are the ones that measure something: what the sanitizer must prevent. With the sanitizer in place, 23 of 23.

If your suite passes entirely against the pass-through, it isn't testing anything.

2. Test the whole document, through the real route

Testing the bare function isn't enough. Also test against the real HTTP route, in the browser with a session cookie, with four inputs:

  • a <script>
  • an onerror=
  • an href with javascript:
  • an onerror inside the html escape hatch

None survived, and the legitimate markup did.

3. Let the tests find the sanitizer's own bugs

Real bugs turn up, for example two:

  • Lowercasing. Lowercasing every name broke SVG: viewBox is case-sensitive.
  • Space after <. Allowing a space between < and the name turned "a < b and c > d" into an open <b>.

Both came out of the sanitizer's own tests.

In short

Three steps: the HTML arrives from the editor, is read tag by tag against the allowed list, and leaves as HTML where every tag was written from scratch. The original tag is never cleaned: it is dropped.

Re-emit every tag from scratch instead of cleaning the one that arrived, test the whole document, and run the test against nothing before running it against the code.

Have a case where you want to see this running? Tell us what your business does and we'll build it on your material.

Comments and corrections

Chat with us