no-unsanitized #9460
kpervin
started this conversation in
Rule suggestion
no-unsanitized
#9460
Replies: 0 comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
Having
no-unsanitizedwould be a huge benefit. Just havingnoDangerouslySetInnerHtmlis a bit cumbersome when the expected workflow is to justify use every single time but still ignoring it.As a proof of concept, I mocked up a possible plugin with Claude Opus 4.6.
README.md
no-unsanitized
A Biome GritQL plugin that flags unsafe DOM manipulation patterns that can lead to Cross-Site Scripting (XSS) vulnerabilities.
Inspired by eslint-plugin-no-unsanitized (Mozilla) and no-sanitizer-with-danger (Jam3).
What it catches
Only unwrapped usages are flagged. Values wrapped in a known sanitizer function are allowed.
Property assignments
el.innerHTML = valueel.innerHTML += valueel.outerHTML = valueel.outerHTML += valueMethod calls
el.insertAdjacentHTML(pos, html)document.write(html)document.writeln(html)range.createContextualFragment(html)el.setHTMLUnsafe(html)React / JSX
dangerouslySetInnerHTML={{ __html: value }}Allowed sanitizers
The plugin does not flag values that are passed through one of these function calls:
DOMPurify.sanitize(...)/dompurify.sanitize(...)— DOMPurifyxss(...)/filterXSS(...)— xsssanitizeHtml(...)— sanitize-htmlsanitize(...)— generic fallback (e.g. custom project sanitizer)Only direct use of these calls is recognized. If you assign the result to a variable and then use that variable (e.g.
const clean = DOMPurify.sanitize(html); el.innerHTML = clean;), the assignment is still flagged because the plugin does not trace variables.Enabling
Add the plugin path to the root
biome.json:{ "plugins": ["<path_to_plugin>/no-unsanitized.grit"] }The plugin runs on all JavaScript, TypeScript, and JSX/TSX files.
Limitations
=and+=are matched for property assignments. Operators like||=,&&=, and??=are not covered.To suppress a single safe usage that still gets flagged:
PLUGIN:
Beta Was this translation helpful? Give feedback.
All reactions