Vue-Router 导航守卫过滤url注入的反射XSS

1,362 阅读1分钟

这事还要从前两天说起:那还是我头一次接到安全工单,出现安全漏洞的是项目中一个预览跳转的页面,工单中提交的隐患URL是这样写的:https://xxxx.xxxx.com/xx?url=javascript:alert(document.cookie)。打开页面发生了神奇的事情,一部分cookie被获取并弹出了。

这个页面并不是我做的,所以研究了一阵逻辑后发现,预览的逻辑是带着一个名为url的参数,使用window.open()打开预览页面,新页面中获取传入的url值后,把该值作为iframe的源填入src属性,完成预览操作。

而这一过程,居然是纯前端操作,任由query自由的在互联网上裸奔。

不过解决办法也很简单,紧急修复就可以先使用vue-router自带的导航守卫,过滤一下参数传递,将非法参数拒之门外。后续稳定修复,就通过一次请求接口,获取预览链接。

以下附上非法参数的正则配对:

router.beforeEach((to, from, next) => {
	/* 其他逻辑 */
	/* 跳转参数判断,url包含可以脚本时拒绝跳转 */
	const query = Object.keys(to.query)
	for (let key of query) {
		const param = to.query[key]
		const illegal = [
			/<(no)?script[^>]*>.*?<\/(no)?script>/gim,
			/eval\((.*?)\)/gim,
			/expression\((.*?)\)/gim,
			/(javascript:|vbscript:|view-source:)+/gim,
			/<("[^"]*"|'[^']*'|[^'">])*>/gim,
			/(window\.location|window\.|\.location|document\.cookie|document\.|alert\(.*?\)|window\.open\()+/gim,
			/<+\s*\w*\s*(oncontrolselect|oncopy|oncut|ondataavailable|ondatasetchanged|ondatasetcomplete|ondblclick|ondeactivate|ondrag|ondragend|ondragenter|ondragleave|ondragover|ondragstart|ondrop|οnerrοr=|onerroupdate|onfilterchange|onfinish|onfocus|onfocusin|onfocusout|onhelp|onkeydown|onkeypress|onkeyup|onlayoutcomplete|onload|onlosecapture|onmousedown|onmouseenter|onmouseleave|onmousemove|onmousout|onmouseover|onmouseup|onmousewheel|onmove|onmoveend|onmovestart|onabort|onactivate|onafterprint|onafterupdate|onbefore|onbeforeactivate|onbeforecopy|onbeforecut|onbeforedeactivate|onbeforeeditocus|onbeforepaste|onbeforeprint|onbeforeunload|onbeforeupdate|onblur|onbounce|oncellchange|onchange|onclick|oncontextmenu|onpaste|onpropertychange|onreadystatechange|onreset|onresize|onresizend|onresizestart|onrowenter|onrowexit|onrowsdelete|onrowsinserted|onscroll|onselect|onselectionchange|onselectstart|onstart|onstop|onsubmit|onunload)+\s*=+/gim
		]
		for (let reg of illegal) {
			if (reg.test(param.toLowerCase())) {
				alert('请求参数不合法!')
				next({ path: to.path, query: {} })
				return
			}
		}
	}
	/* 其他逻辑 */
	next()
})

其实方便自己以后回来面向CV编程~