什么是XSS攻击
你打开一个网页,攻击点了篇文章,攻击页面突然弹出一个登录框,攻击要求你重新输入账号密码。攻击你照做了。攻击第二天,攻击你的攻击社交账号开始给所有好友发垃圾广告。问题不在你,攻击在那个网页——它被注入了恶意脚本,攻击你的攻击密码直接进了攻击者的口袋。这就是攻击XSS,跨站脚本攻击。攻击 它的攻击原理不复杂。网站把用户输入的攻击内容直接显示在页面上,没有做过滤。攻击攻击者提交一段JavaScript代码,这段代码被服务器“原样”返回给其他访问者,浏览器分不清这是网站自己的脚本还是外来的恶意代码,照常执行。于是,cookie被偷、页面被篡改、键盘输入被监听,全在用户毫无察觉的情况下发生。 2005年,MySpace上有个叫Samy的人,写了一小段CSS加JavaScript的蠕虫代码。任何查看他主页的用户,都会自动把他加为好友,并在自己主页上复制这段代码。20小时内,超过100万用户中招。MySpace不得不紧急关站清理。这是XSS最经典的案例之一,也说明了一个问题:XSS不只是弹个警告框那么简单,它能自我复制、大规模传播。 XSS分三类,区别在于恶意脚本的“落脚点”不同。 存储型最危险。代码被存进数据库,比如一条评论、一个用户名。每个访问该页面的用户都会触发。我见过一个电商网站,商品评价区没做过滤,有人留了一段脚本,所有看这条评价的人,购物车里的商品都会被自动下单。网站三天后才发现,损失六位数。 反射型更常见。恶意代码藏在URL参数里,服务器把它“反射”回页面。典型场景是钓鱼邮件:你收到一条链接,点进去是某个你信任的网站,但URL里夹了脚本。页面加载时脚本执行,你根本看不出异常。这类攻击需要诱导点击,但成功率不低——因为域名是真的。 DOM型最隐蔽。恶意代码不经过服务器,纯粹在浏览器端由JavaScript动态写入页面。服务器日志里看不到任何异常,传统的WAF(Web应用防火墙)也拦不住。前端框架用多了,这类漏洞反而在增加。 防御的核心就一句话:永远不要信任用户输入。具体做法有几种。输出编码——把 但现实是,很多开发者觉得“我这个小网站没人盯上”。错了。自动化扫描工具每天在互联网上爬,专门找没做过滤的输入框。你的网站可能不值钱,但你的用户的cookie值钱。攻击者用你的站点当跳板,偷的是你用户的银行会话。 我自己的习惯:写任何涉及用户输入的功能时,先假设这段输入是 最后说个细节。很多人以为前端框架自动防XSS,React的JSX确实默认转义,但如果你用了<转成<,让浏览器把它当文本而不是标签。输入验证——该是数字的地方只允许数字,该是邮箱的地方严格匹配格式。Cookie加HttpOnly标记,JavaScript就读不到,偷不走。CSP(内容安全策略)限制页面只能加载指定来源的脚本,即使注入了恶意代码,浏览器也拒绝执行。<script>alert(1)</script>,然后问自己——它会在哪里被输出?输出时经过编码了吗?如果答案模糊,那就重写。XSS不挑语言,PHP、Java、Python、Node.js都中招。它挑的是疏忽。dangerouslySetInnerHTML,或者Vue里用了v-html,防护就没了。工具是工具,意识是意识。漏洞永远在人的判断里,不在代码里。