Configure a sanitizer for user comments

A comment feature keeps the formatting users submit, but its sanitizer configuration re-enables event handlers, unknown URL schemes and extra tags, so a comment can run script. Repair the configuration so only a small set of formatting tags and safe links survive.

Requires Node.js 22 or newer. The DOM cases need jsdom and DOMPurify: run npm install jsdom dompurify@3.4.16 in this folder first. Without it those cases report that they did not run. No server needed. To work in a container instead, open the folder with VS Code Dev Containers or GitHub Codespaces: .devcontainer/devcontainer.json uses the Dev Containers Node.js 24 image, pinned by digest.
1. Unzip all files into one folder.
2. In that folder, run: node --test exercise.test.mjs
3. Edit comment-policy.mjs, then run the same command again.

The starter deliberately fails some tests. A successful repair passes every case, including cases that catch common wrong fixes. The browser runs this same cases.mjs with the same fixtures; locally Node runs your code directly. If you completed the optional first stage in the browser, Download my work adds your input as stage1-input.json and the tests include it. Only run code you wrote or reviewed.

1. Reproduce the escape
Run the starter. Its configuration adds onerror and onclick back as allowed attributes, adds style and iframe as allowed tags, and allows any URL scheme, so a comment with an image error handler or a javascript: link runs script.

2. List the tags you allow
Set ALLOWED_TAGS to exactly p, strong, em, ul, ol, li and a. An allowlist of formatting tags is safe; adding style, iframe, img or svg is not.

3. Allow one safe attribute
Set ALLOWED_ATTR to only href. Never add on* handlers, style or src. An event-handler attribute is script.

4. Restrict link schemes
Set ALLOWED_URI_REGEXP so an href must be an absolute https: URL, and remove ALLOW_UNKNOWN_PROTOCOLS. Anchor the pattern with ^: DOMPurify keeps an href that the pattern matches anywhere, so /https:/ also keeps javascript:steal()//https://x. Keep a normal https link; drop javascript:, data:, plain http and relative links.

SUPPLIED CONTRACT
Export commentPolicy, an options object passed to DOMPurify.sanitize(html, commentPolicy) (DOMPurify 3). The grader runs DOMPurify with your options in a real DOM and inspects the result. Comments may use only p, strong, em, ul, ol, li and a, and the only attribute is href on a; a link’s href must be an absolute https: URL. Use ALLOWED_TAGS and ALLOWED_ATTR for the allowlists and ALLOWED_URI_REGEXP to limit link schemes; do not re-enable anything with ADD_TAGS, ADD_ATTR or ALLOW_UNKNOWN_PROTOCOLS. You configure the sanitizer; you do not write the sanitizing code.

REFERENCE
reference.mjs contains an explained solution: With ALLOWED_TAGS limited to the seven formatting tags, a comment’s script, img, style, iframe and svg are dropped while its p, strong, em, lists and links stay. With ALLOWED_ATTR limited to href, onerror, onclick, style and src attributes are removed, so an image error handler cannot run even if an img slipped through. ALLOWED_URI_REGEXP of ^https: keeps an https link and removes a javascript:, data: or relative href. The ^ matters: the pattern is tested against the whole href, so an unanchored /https:/ keeps javascript:steal()//https://x and http://evil.test/?https: because https: appears somewhere in them. The text of every comment is preserved, because sanitizing strips disallowed markup, not content.

SCOPE
This configures DOMPurify 3; it is not the whole rich-text pipeline. Sanitize on the server after converting Markdown to HTML and before the HTML reaches a sink, keep the library current, and set a Content-Security-Policy as a second layer. A stricter link rule (no credentials, a host allowlist) needs an afterSanitizeAttributes hook, which this lab does not cover. DOMPurify returns a string; build the DOM from it with a safe sink, never with the raw comment.

NEXT TASK
Does your sanitizer run from an allowlist you control, and is it applied after every transformation that could reintroduce markup?

SOURCE
https://github.com/cure53/DOMPurify#can-i-configure-dompurify
