✅ 框架与 XSS 防护概况
| 框架 | 是否默认转义 | 高危场景 | 建议防御措施 |
|---|---|---|---|
| React | ✅ 是 | 使用 dangerouslySetInnerHTML | 避免使用,必要时做内容清洗 |
| Vue.js | ✅ 是 | 使用 v-html | 避免使用,或使用 DOMPurify 清洗 |
| Angular | ✅ 是 | 使用 innerHTML、bypassSecurityTrustHtml | 谨慎绕过安全策略 |
| Django (模板) | ✅ 是 | 使用 ` | safe` |
| Flask / Jinja2 | ✅ 是 | 使用 ` | safe` |
| Spring Boot (Thymeleaf) | ✅ 是 | 使用 th:utext | 默认 th:text 安全,慎用 utext |
| Express + EJS / Handlebars | ❌ 否 | 直接拼接 HTML 输出 | 使用模板语法自动转义 |
| PHP 原生 / Smarty | ❌ 否 | 直接 echo 用户输入 | 使用 htmlspecialchars() + 模板转义 |
📍 React 中的 XSS 风险
⚠️ 危险代码示例:
function Comment({ content }) {return <div dangerouslySetInnerHTML={{ __html: content }} />;
}
用户输入含
<script>会被执行!
✅ 防御做法:
import DOMPurify from 'dompurify';<div dangerouslySetInnerHTML={{ __html: DOMPurify.sanitize(content) }} />
📍 Vue.js 中的 XSS 风险
⚠️ 危险代码示例:
<div v-html="userContent"></div>
✅ 防御做法:
import DOMPurify from 'dompurify';
this.safeContent = DOMPurify.sanitize(userContent);
📍 Angular 中的 XSS 风险
⚠️ 危险代码示例:
this.trusted = this.sanitizer.bypassSecurityTrustHtml(userInput);
✅ 防御做法:
- 避免滥用
bypassSecurityTrustHtml - 使用默认绑定方式或手动清洗内容
📍 Django 模板中的 XSS 风险
⚠️ 危险代码示例:
{{ comment|safe }}
✅ 防御做法:
- 避免使用
|safe,除非你非常确信内容安全 - 默认
{{ comment }}会自动 HTML 转义
📍 Express + EJS 模板中的 XSS 风险
⚠️ 危险代码示例:
<div><%- userInput %></div> <!-- 非转义输出 -->
✅ 防御做法:
<div><%= userInput %></div> <!-- 自动 HTML 转义 -->
📍 Spring Boot + Thymeleaf 的 XSS 风险
⚠️ 危险代码示例:
<span th:utext="${userInput}"></span>
✅ 防御做法:
<span th:text="${userInput}"></span> <!-- 自动 HTML 转义 -->
🧠 总结建议
- ✅ 默认转义机制是第一道防线,慎重绕开!
- 🚫 避免使用不安全输出语法如
|safe、v-html、dangerouslySetInnerHTML等 - 🧼 推荐使用 DOMPurify 对富文本内容做清洗
- 🔐 后端应区分内容用途,做针对性输出处理
📌 推荐工具
- 富文本清洗:
DOMPurify、xss(Node.js 库)