百度空间 | 百度首页 
               
 
查看文章
 
Anehta -- 打造一个Browser Sniffer
2008-11-04 11:29
0.5.6 中加入了对BrowserSniffer的支持。

一般简单的判断客户端浏览器类型的方法,都是读取客户端的userAgent

比如 navigator.appVersionnavigator.userAgent

然后从UA信息中,取出浏览器版本和操作系统版本进行判断。

比如我的userAgent 信息大致是这样的:


在jQuery 中的就是这么判断浏览器版本的。

但是userAgent 的信息是可以伪造的,甚至有很多工具可以让用户直接修改UA信息,这样通过获取UserAgent来判断浏览器就不再准确了。


Anehta 对客户端浏览器的判断要求比较高,所以在这里采用了Browser Sniffer技术。

其实就是通过各个浏览器的一些DOM对象或者是方法之间的差异,进而判断出准确的浏览器版本。

在 anehta.detect.browser() 函数中实现如下过程:
anehta.detect.browser = function (){
    var userAgent = navigator.userAgent.toLowerCase();
   
    return {
        type : function(){
            /* 独立于jQuery实现
            //$.browser.msie/safari/opera/mozilla
            if($.browser.msie){ return "msie";}
            else if($.browser.mozilla){return "mozilla";}
                else if($.browser.opera){return "opera";}
                    else if($.browser.safari){return "safari";}
                        else {return "unknown";}
            */
            //alert(navigator.userAgent);
           
            // 通过一些dom对象判断浏览器指纹 ie,ie7,ie8,ff2,ff3,safari,opera,chrome,maxthon,theworld,360se....
            //if (typeof document.all != "undefined"){ // msie ; firefox 在 quirks mode下也支持
            if (window.ActiveXObject){
                anehtaCache.setItem("BrowserSniffer", "MSIE 6.0 or below");
           
            // 判断是否是IE7以上
            if (document.documentElement && typeof document.documentElement.style.maxHeight!="undefined" ){
               
                // 判断是否是 IE8+
                if ( typeof document.adoptNode != "undefined") { // Safari3 & FF & Opera & Chrome & IE8
                    anehtaCache.setItem("BrowserSniffer", "MSIE8.0");
                }
                // 因为是精确判断,所以改写cache
                anehtaCache.setItem("BrowserSniffer", "MSIE7.0");
            }
               
            // 不可靠的判断一些浏览器
            if (userAgent.indexOf("maxthon") > -1){
                anehtaCache.appendItem("BrowserSniffer", " | "+"maybe maxthon");   
            }
            if (userAgent.indexOf("360se") > -1){
                anehtaCache.appendItem("BrowserSniffer", " | "+"maybe 360se");   
            }
            if (userAgent.indexOf("theworld") > -1) {
                anehtaCache.appendItem("BrowserSniffer", " | "+"maybe theworld");   
            }
            /*
            if (userAgent.indexOf("") > -1) {
                //anehtaCache.appendItem("BrowserSniffer", " | "+"maybe greenbrowser");
            }
            */
           
            return "msie";
            }
            else if (typeof window.opera != "undefined") { //opera独占
                anehtaCache.setItem("BrowserSniffer", "Opera "+window.opera.version());
                return "opera";
            }
            else if (typeof window.netscape != "undefined") { // mozilla 独占
                anehtaCache.setItem("BrowserSniffer", "Mozilla");       
                // 可以准确识别
                if (typeof window.Iterator != "undefined") {
                anehtaCache.setItem("BrowserSniffer", "Firefox 2");
               
                if (typeof document.styleSheetSets != "undefined") { // Firefox 3 & Opera 9
                    anehtaCache.setItem("BrowserSniffer", "Firefox 3");
                }
                }
                return "mozilla";
            }
            else if (typeof window.pageXOffset != "undefined") { // mozilla & safari
                anehtaCache.setItem("BrowserSniffer", "Safari");
        try{
                if (typeof external.AddSearchProvider != "undefined") { // firefox & google chrome
                    anehtaCache.setItem("BrowserSniffer", "Google Chrome");
                    return "chrome";
                }
            } catch (e) {
                    return "safari";
            }
            }   
      else { //unknown
                anehtaCache.setItem("BrowserSniffer", "Unknown << "+userAgent+" >>");
            return "unknown";   
            }
        },
       
        // 从userAgent里取出来的不可靠
        version : function(){
            //return $.browser.version;   
            return (userAgent.match( /.+(?:rv|it|ra|ie|me)[\/: ]([\d.]+)/ ) || [])[1];
        }
    };
};

最终准确的判断 结果保存在了cache中的 “BrowserSniffer” 字段里,所以如果XSS抓回来的UserAgent 信息和 BrowserSniffer 信息不一致,就可以知道,UA已经被伪造过了!


类别:象牙塔 | 添加到搜藏 | 浏览() | 评论 (7)
 
最近读者:
 
网友评论:
1
2008-11-04 11:54 | 回复
haha。
 
2
2008-11-04 11:55 | 回复
沙发
 
3
2008-11-04 12:05 | 回复
太勤快了!!
 
4
2008-11-04 13:39 | 回复
太bt了,抽空研究下,拿来为我所用,你搞破坏,我搞个auti破坏的,hoho。
 
5
2008-11-04 21:28 | 回复
谢谢了。
 
6
2008-11-06 13:37 | 回复
大风大哥的杰作啊,哈哈,连续N多篇BLOG都是这个。 怎么BLOG集合里面没有了呢?
 
7
2008-11-06 14:07 | 回复
Planet里好像有啊,你找找看?
 
发表评论:
姓 名:
网址或邮箱: (选填)
内 容:
验证码: 请点击后输入四位验证码,字母不区分大小写
      

     

©2009 Baidu