可以通过返回伪造的安装字体列表来阻止浏览器指纹识别?

时间:2011-01-07 12:10:27

标签: browser fonts privacy

是否可以编写一个掩盖计算机上安装的字体集的程序,因此字体列表将显示为“普通的”,并且在创建一个独特的指纹时没有多大价值? https://panopticlick.eff.org/

2 个答案:

答案 0 :(得分:1)

在某些浏览器中可能会有一些支持,但是使用任何浏览器都可以拦截winapi调用以枚举字体列表。

基本上你编写了一个将加载到浏览器进程中的dll,然后它将拦截浏览器在枚举字体时对操作系统进行的调用。只需查找Windows中的哪些函数用于枚举字体,并在你的dll中伪造它们。 (这可能是一些工作,因为你将不得不重写字体枚举逻辑)。

另外,有些浏览器可能只是读取注册表来枚举字体,而不是使用专门的字体功能,在这种情况下你必须拦截注册表-winapi函数,并确保它们报告字体列表你想要的。

要将dll加载到目标进程中,可以使用Windows挂钩,或使用.exe文件编辑器将dll添加到浏览器exe文件的导入表中。注册表中还有一个特殊的位置,如果在那里添加一个dll,它将被加载到系统中的每个进程。 (那么你必须检查浏览器进程,然后只拦截api调用,这样你系统上的每个程序都不会得到伪造的字体列表。)

此外,浏览器可能会在另一个进程中运行某些插件,或者activex控件,或者类似的东西(例如,chrome运行不同进程中的每个选项卡),所以我会检查每个进程的父进程,如果您发现它已由浏览器启动,则也会拦截该进程中的字体列表。这样,目标网页将无法通过flash,插件,java或其他任何东西获得真实的字体列表。

可以在此处找到拦截winapi电话的良好开端:http://www.codeproject.com/KB/system/InterceptWinAPICalls.aspx

所以这是一种可行的方法,虽然它不能在一小时内完成,但它也不会过于复杂。

当然,这不仅会使您的字体列表变得虚假,还会使浏览器看不到并能够显示列表中没有的字体。

当然,这一切对Windows都有效,但在其他操作系统上肯定会有类似的方法。

另外,值得注意的是,如果你禁用了javascript和插件(flash),我认为网页不能读取字体列表。

答案 1 :(得分:0)

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
    <head>
        <title>Font detector</title>
        <style type="text/css" media="screen">

            #font_detector_box{ visibility: hidden; }
            #font_detector_box span.font{ padding: 0px; margin: 0px; border: none;  font-size: 10px; letter-spacing: 1px; }

        </style>        
    </head>
    <body>
        <h1>Font Detection Page</h1>
        <p>This page is a sample for font detection tecniques</p>

        <h2>List of fonts installed on your machine</h2>
        <span id="font_list_display">
        </span>

        <!-- Invisible div -->
        <div id="font_detector_box">            
            <span class="font family_Arial" style="font-family: Arial, Verdana !important">mmm</span>
            <span class="font family_Comics_Sans_MS" style="font-family: Comic Sans MS, Arial !important">mmm</span>
            <span class="font family_Georgia" style="font-family: Georgia, Arial !important">mmm</span>
            <span class="font family_Helvetica" style="font-family: Helvetica, Verdana !important">mmm</span>           
            <span class="font family_Verdana" style="font-family: Verdana, Arial !important">mmm</span>
            <span class="font family_Times_New_Roman" style="font-family: Times New Roman, Arial !important">mmm</span>
        </div>

    </body>
    <script type="text/javascript"src="https://ajax.googleapis.com/ajax/libs/jquery/1.5.0/jquery.min.js"></script>
    <script type="text/javascript">

        var fontMeasures = new Array( );

        //Web safe
        fontMeasures["Arial"] =  new Array( "30px", "13px" );
        fontMeasures["Comics_Sans_MS"] = new Array( "27px" , "14px" );
        fontMeasures["Georgia"] = new Array( "33px" , "13px" );     
        fontMeasures["Helvetica"] = new Array( "30px" , "13px" );
        fontMeasures["Verdana"] = new Array( "36px" , "12px" );
        fontMeasures["Times_New_Roman"] = new Array( "27px" , "12px" );

        var msg = "";

        $( ".font" , "#font_detector_box" ).each( function( ){

            var fontFamily = $( this ).attr( "class" ).toString( ).replace( "font " , "" ).replace( "family_" , "" );

            var width = $( this ).css( "width" );

            var height = $( this ).css( "height" );

            //alert( width + height );

            if( fontMeasures[fontFamily][0] === width && fontMeasures[fontFamily][1] === height ){

                var family = fontFamily.replace( /_/g , " " );

                msg += '<span class="font-family: '+ family + ';">' + family + '</span> <br/>';

            }           

        });

        $( "#font_list_display" ).html( msg );

    </script>
</html>