Skip to content

Instantly share code, notes, and snippets.

@footearth
Last active April 22, 2016 16:44
Show Gist options
  • Save footearth/e42c34ef351578c66108 to your computer and use it in GitHub Desktop.
Save footearth/e42c34ef351578c66108 to your computer and use it in GitHub Desktop.
Web 前端攻防(2014版)---- Opener 钓鱼

Opener

浏览器提供了一个 opener 属性,供弹出的窗口访问来源页。但该规范设计的并不合理,导致通过超链接打开的页面,也能使用 opener。

因此,用户点了网站里的超链接,导致原页面被打开的第三方页面控制。

虽然两者受到同源策略的限制,第三方无法访问原页面内容,但可以跳转原页面。

由于用户的焦点在新打开的页面上,所以原页面被悄悄跳转,用户难以觉察到。当用户切回原页面时,其实已经在另一个钓鱼网站上了。

防范措施

该缺陷是因为 opener 这个属性引起的,所以得屏蔽掉新页面的这个属性。

但通过超链接打开的网页,无法被脚本访问到。只有通过 window.open 弹出的窗口,才能获得其对象。

所以,对页面中的用户发布的超链接,监听其点击事件,阻止默认的弹窗行为,而是用 window.open 代替,并将返回窗体的 opener 设置为 null,即可避免第三方页面篡改了。

详细实现参考:http://www.etherdream.com/FunnyScript/opener_protect.html

当然,实现中无需上述 Demo 那样复杂。根据实际产品线,只要监听用户区域的超链接就可以。

function handleHyperLink(e) {
var el = e.target;
var link;
// 是否点击 <a> 里面的元素
while (el) {
var tag = el.tagName;
if (tag == 'A') {
link = el;
break;
}
if (tag == 'BODY' || tag == 'HTML') {
return;
}
el = el.parentNode;
}
if (!link) {
return;
}
// 只处理新窗口的超链接
var REG = /^(_parent|_self|_top)$/;
var redir = REG.test(el.target);
if (redir) {
var base = document.getElementsByTagName('base')[0];
if (!base || REG.test(base.target)) {
return;
}
}
// 包装原有回调
var raw = el.onclick;
//
// 在 AT_TARGET 阶段处理点击行为,
// 允许用户在冒泡中屏蔽该事件。
//
el.onclick = function(e) {
el.onclick = raw;
// 源函数是否拦截事件
if (raw) {
var ret = raw.apply(this, arguments);
if (ret === false) {
return false;
}
}
e.preventDefault();
// 删除新页面的 opener 属性
var win = window.open(el.href);
win.opener = null;
};
}
document.addEventListener('click', handleHyperLink, true);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment