← 返回博客
·安全相关

XSS 防御指北:那些你以为防住了但没防住的缺口

XSS 是最容易出问题的 Web 漏洞类型,聊聊代码审计中的高频失误场景,以及真正的纵深防御分层方案。

#XSS#Web安全#CSP

# XSS 防御指北:那些你以为防住了但没防住的缺口

做 Web 安全这几年,发现 XSS 是最容易出问题的漏洞类型。不是因为开发者不知道 XSS,而是——太多人以为自己防住了,实际上只是防了个寂寞。

今天不聊 XSS 是什么,那玩意儿随便搜一搜都有。聊点实战向的:我在代码审计里见过的高频失误,以及真正的防御方案。

误区一:以为转义了 HTML 特殊字符就万事大吉

很多人写后端接口的时候,会对用户输入做类似这样的处理:

function escapeHtml(str) {

return str

.replace(/&/g, '&')

.replace(/</g, '&lt;')

.replace(/>/g, '&gt;')

.replace(/"/g, '&quot;')

.replace(/'/g, '&#x27;');

}

然后心想:这下总没问题了吧?

不好意思,问题大了。

这个转义只在**把字符串渲染进 HTML 文本节点**时才有效。如果你的页面用了 Vue/React 的模板语法,框架本身会帮你做转义;但如果你的代码里有这样的场景,这层转义形同虚设:

**场景1:直接 innerHTML 赋值**

// 后端传过来的"安全"字段,直接塞进 innerHTML

element.innerHTML = escapeHtml(userInput); // 错!根本不该用 innerHTML

**场景2:URL 参数注入到 src/href**

<a href="https://example.com/search?q=USER_INPUT">链接</a>

<img src="https://img.example.com/USER_INPUT" />

这时候 >< 不被解析为 HTML,但能被解析为 URL 组成部分。如果输入是 x.jpg?onerror=alert(1),且后端没做校验,问题就来了。

**场景3:JSON 注入**

<script>

const data = <?php echo json_encode($userInput); ?>;

</script>

如果 $userInput 里包含