Security warn by default
astro-doctor/no-set-html no-set-html
Avoid set:html to prevent cross-site scripting (XSS) vulnerabilities.
Why
set:html injects raw HTML into the DOM without escaping. Any user-controlled or third-party content rendered this way is an XSS vector. Use Astro's JSX interpolation (which escapes by default) or sanitize the content first.
Examples
✗ Incorrect
Unsanitized HTML injection
---
const userContent = await fetchUserBio()
---
<div set:html={userContent} /> ✓ Correct
Escaped interpolation (or sanitized HTML)
---
import DOMPurify from 'dompurify'
const userContent = await fetchUserBio()
const safe = DOMPurify.sanitize(userContent)
---
{/* Escaped by default */}
<p>{plainTextContent}</p>
{/* Only if HTML rendering is truly required */}
<div set:html={safe} /> Configuration
Override the default severity in your ESLint config:
// eslint.config.js
import astroDoctorPlugin from '@santi020k/eslint-plugin-astro-doctor'
export default [
astroDoctorPlugin.configs.recommended,
{
rules: {
'astro-doctor/no-set-html': 'error', // or 'warn' or 'off'
},
},
]
Or in your doctor.config.ts:
export default {
rules: {
'astro-doctor/no-set-html': 'error',
},
}
All rules
-
astro-doctor/no-client-load-overuse -
astro-doctor/use-astro-image -
astro-doctor/require-image-dimensions -
astro-doctor/no-missing-alt -
astro-doctor/no-set-html(this page) -
astro-doctor/no-public-secret-env -
astro-doctor/prefer-class-list -
astro-doctor/no-blocking-script -
astro-doctor/no-unprocessed-script-surprises -
astro-doctor/no-missing-lang -
astro-doctor/require-island-fallback -
astro-doctor/no-process-env -
astro-doctor/prefer-content-collections