JustHTML includes a built-in HTML sanitizer. When you parse HTML with JustHTML(html), it is sanitized by default according to a strict allowlist policy. You do not need a separate library.
JustHTML protects against:
<script>), attributes (onload), and schemes (javascript:).The sanitizer is validated against justhtml-xss-bench (7,000+ real-world XSS vectors). The benchmark can be used to compare JustHTML’s output against established sanitizers like nh3 and bleach.
Preventing Cross-Site Scripting (XSS) requires more than just cleaning HTML tags. Security depends entirely on context. A string that is safe to display in a <div> might be dangerous inside a <script> tag or an HTML attribute.
Therefore, you must choose the correct output method when embedding data in contexts other than standard HTML.
JustHTML(html, fragment=True).to_html() for snippets, or JustHTML(html).to_html() for full page documents. (Safe by default)JustHTML.escape_js_string() for strings, clean_url_in_js_string() for URLs.JustHTML.escape_attr_value() for values, clean_url_value() for URLs.If you are rendering HTML into the body of a page (server-side rendering), JustHTML safeguards you automatically. By default, JustHTML(...) sanitizes input using a conservative policy (strips scripts, allowlists safe tags).
Most real-world untrusted HTML is a snippet (a comment, a bio, a post) meant to be inserted into an existing page. Pass fragment=True to parse it without adding <html>/<body> wrappers.
from justhtml import JustHTML
# Safe for embedding in a <div>
html = JustHTML(user_html, fragment=True).to_html()
# Output: <p>User content...</p>
If you are sanitizing a complete HTML document (e.g. an uploaded file or email), omit fragment=True. JustHTML will preserve or add the necessary <html>, <head>, and <body> structure.
# Safe full document
doc = JustHTML(full_html_string).to_html()
# Output: <html><head></head><body>...</body></html>
This is where most XSS vulnerabilities occur. If you embed HTML or data into <script> blocks or event handlers, simple HTML cleaning is not enough. You need specialized escaping.
If you need to put a block of HTML into a variable (e.g., for a client-side template):
from justhtml import JustHTML, HTMLContext
# Safe for: const myHtml = "${safe}";
safe = JustHTML(user_html, fragment=True).to_html(context=HTMLContext.JS_STRING)
innerHTML via JSRecommendation: Use element.textContent = ... instead. It safer and handles escaping automatically. You only need escape_js_string() for that (see below).
If you must assign text to .innerHTML (e.g. legacy code), you need to escape HTML entities and JS characters:
from justhtml import JustHTML
# Safe for: element.innerHTML = "${safe}";
safe = JustHTML.escape_html_text_in_js_string(user_text)
If the string is just data (not HTML):
from justhtml import JustHTML
# Safe for: const label = "${safe}";
safe = JustHTML.escape_js_string(user_text)
If you are setting location.href or similar from untrusted input, you must clean the URL (validate scheme/host) before escaping it.
from justhtml import JustHTML, UrlRule
rule = UrlRule(allowed_schemes={"https"})
# Safe for: location.href = "${clean}";
clean = JustHTML.clean_url_in_js_string(value=user_url, url_rule=rule)
When inserting data into HTML attributes (like title="..." or class="..."), you must escape double quotes to prevent the value from closing the attribute early.
from justhtml import JustHTML
# Safe for: <input value="${safe}">
safe = JustHTML.escape_attr_value(user_input)
If the attribute expects a URL (like href, src, or action), simple escaping is safer than nothing but often insufficient (e.g. javascript:alert(1) contains no quotes). You must validate the URL first.
from justhtml import JustHTML, UrlRule
rule = UrlRule(allowed_schemes={"https", "mailto"})
cleaned_url = JustHTML.clean_url_value(value=user_url, url_rule=rule)
if cleaned_url:
# URL is safe to use.
# Note: clean_url_value performs URL encoding, so no extra escape needed if using double quotes in HTML.
# <a href="${cleaned_url}">
pass
JustHTML is secure by default, but you can customize the allowlist to fit your application’s needs.
mailto:, tel:) and hosts.