stay hungry stay foolish

xss攻击

跨站脚本攻击(Cross Site Scripting)本来的缩写为CSS,为了与层叠样式表(Cascading Style Sheets,CSS)的缩写进行区分,将跨站脚本攻击缩写为XSS。XSS 是一种经常出现在web应用中的计算机安全漏洞,它允许恶意web用户将代码植入到提供给其它用户使用的页面中。攻击者利用XSS漏洞躲避访问控制——例如同源策略(same origin policy)。

XSS 攻击

XSS 攻击通常分为两种:

  • 反射型
  • 存储型

反射型即攻击脚本不需要存储,攻击脚本直接添加到 URL 参数里,未做 XSS 防范的服务器会解析参数并返回含有攻击脚本的页面给用户。

index.js

var express = require('express');
var router = express.Router();
var comment = null;

router.get('/', function(req, res, next) {
    res.render('index');
});

router.get('/xss1', function(req, res, next) {
	var xss = req.query.xss
    res.render('index', { xss: xss });
});

router.get('/xss2', function(req, res, next) {
	var xss = req.query.xss
	res.set('X-XSS-Protection',0); // 关闭浏览器XSS拦截
    res.render('index', { xss: xss });
});

router.post('/add', function(req, res, next) {
	comment = req.body.comment;
    res.render('index');
});

router.get('/get', function(req, res, next) {
    res.render('index',{ comment: comment });
});

module.exports = router;

index.jade

extends layout

block content
	h1 xss demo
	//-'!='代表不转义
	p!= xss
	form(action="/add", method="post")
		textarea(name="comment",rows=10,cols=50)
		<br>
		input(type="submit" value="提交评论")
		<br>
	p
		a(href="/get") 获取评论
		p!= comment

完整示例代码

运行 express 并打开连接 http://localhost:3000/xss1?xss=<img src='null' onerror='alert(1)'>

结果:

可以看到,默认情况下,浏览器会拦截反射型 XSS 攻击,浏览器会判断待执行的脚本代码是否存在于浏览器的 URL 中,如果是,就不会执行,当然,可以通过设置 Header 强制执行。

运行http://localhost:3000/xss2?xss=<img src='null' onerror='alert(1)'>

结果:

以上是简单的反射型 XSS 攻击示例,在实际情况下,黑客会在攻击脚本里插入获取用户 cookie 的代码,获取成功后再将 cookie 信息通过链接发送到目标服务器。用户只要点击了该带有 XSS 攻击的链接,就有可能泄露自己的信息。

存储型 XSS 攻击一般需要服务器将黑客注入的脚本存储到服务器上,因为攻击脚本不在 URL 里,浏览器是无法拦截的,这种情况,只有在服务器端做防范。

打开连接 http://localhost:3000/

输入攻击脚本,点击添加按钮,然后再点击获取评论。此时,攻击脚本就执行了。

XSS 防范

明白原理,要防范 XSS 攻击就简单多了,防范主要是在后端进行,一般有如下几种方法:

  • 将页面提交的内容进行转义。
  • 如果需要处理标签,则将 script、link、style、iframe、frame 等标签过滤掉,另外 onerror、onclick 等事件属性也需要过滤掉。