关于PHP的is_a()函数执行代码的问题

标签: 象牙塔 | 发表时间:2011-09-29 07:42 | 作者:aullik5 Sam
出处:http://hi.baidu.com/aullik5

    今天看到云舒在群里贴的漏洞公告,原始的文章在

http://www.byte.nl/blog/2011/09/23/security-bug-in-is_a-function-in-php-5-3-7-5-3-8/

    后来查了下PHP官方的手册,这个问题是在PHP 5.3.7中更新了is_a()函数的功能。is_a()经常被用于条件判断。

    在此前版本的is_a() 的第一个参数如果不是object,则会返回false,现在变成了如果不是object ,则会去执行 __autoload()函数。PHP为此还开了一个bug,但对此bug仍然有争议,部分开发人员认为这个功能是正常的。

 

Aron Budinszky 07-Sep-2011 11:21

Be careful! Starting in PHP 5.3.7 the behavior of is_a() has changed slightly: when calling is_a() with a first argument that is not an object, __autoload() is triggered!

In practice, this means that calling is_a('23', 'User'); will trigger __autoload() on "23". Previously, the above statement simply returned 'false'.

More info can be found here:
https://bugs.php.net/bug.php?id=55475

Whether this change is considered a bug and whether it will be reverted or kept in future versions is yet to be determined, but nevertheless it is how it is, for now...

 

    但是需要注意的是,PHP是否会对这个问题做出修补仍属未知!在昨天发布的PHP 5.4 beta1 中,并未见到修复了此问题。

    这是一个类似于PHP的unserialize()函数可以执行__destruct()/__wakeup()中代码的问题

    漏洞的触发是控制 is_a()函数的第一个参数,该参数会被当做输入传入__autoload()函数,并自动执行__autoload()函数中的代码。能够执行什么功能,取决于__autoload()函数的功能。

    验证此问题如下:

测试代码:

<?php

 

function __autoload($classname){

  include_once $classname;

}

 

function test($str){

  print "this is a test<br>";

 

  $object = $str;

  if (!is_a($object, 'SAFE')){

    die("not safe!<br>");

  }

}

 

test($_GET["a"]);

 

?>

测试结果:

    但是一般来说,__autoload()函数的功能会用于加载一个文件,比如在DEDECMS中的用法:

//自动加载类库处理

function __autoload($classname)

{

    global $cfg_soft_lang;

    $classname = preg_replace("/[^0-9a-z_]/i", '', $classname);

    if( class_exists ( $classname ) )

    {

        return TRUE;

    }

    $classfile = $classname.'.php';

    $libclassfile = $classname.'.class.php';

        if ( is_file ( DEDEINC.'/'.$libclassfile ) )

        {

            require DEDEINC.'/'.$libclassfile;

        }

        else if( is_file ( DEDEMODEL.'/'.$classfile ) ) 

        {

            require DEDEMODEL.'/'.$classfile;

        }

        else

        {

            if (DEBUG_LEVEL === TRUE)

            {

                echo '<pre>';

echo $classname.'类找不到';

echo '</pre>';

exit ();

            }

            else

            {

                header ( "location:/404.html" );

                die ();

            }

        }

}

 

    此处在加载文件前判断了文件名只能为/[^0-9a-z_]/i 中的字符,相对较为安全。

 

    但在另外某知名CMS中,则没有做任何判断:

function __autoload($class) {

    include_once $class.'.php';

 

    if(!class_exists($class,false)) exit('系统加载类失败,类'.$class.'不存在!');

}

    

 

    由于这个漏洞是需要is_a()函数配合 __autoload() 才能利用,且对PHP版本有要求,因此实际中能够找到利用的地方相对较少。但若是PHP官方坚持不认为这是个漏洞,在未来可能会成为一个一直可以利用的弱点。在PHP5.4中is_a()可能会支持string类型参数,同时此漏洞应该已经上报给了CVE。

 

阅读全文
类别:象牙塔 查看评论

相关 [php is 函数] 推荐:

PHP-CGI 进程 CPU 100% 与 file_get_contents 函数的关系

- ArBing - 张宴的博客
  [文章作者:张宴 本文版本:v1.0 最后修改:2011.08.05 转载请注明原文链接:http://blog.s135.com/file_get_contents/].   有时候,运行 Nginx、PHP-CGI(php-fpm) Web服务的 Linux 服务器,突然系统负载上升,使用 top 命令查看,很多 php-cgi 进程 CPU 使用率接近100%.

关于PHP的is_a()函数执行代码的问题

- Sam - 大风起兮云飞扬
    今天看到云舒在群里贴的漏洞公告,原始的文章在.     后来查了下PHP官方的手册,这个问题是在PHP 5.3.7中更新了is_a()函数的功能. is_a()经常被用于条件判断.     在此前版本的is_a() 的第一个参数如果不是object,则会返回false,现在变成了如果不是object ,则会去执行 __autoload()函数.

8个很有用的PHP安全函数,你知道几个?

- - CSDN博客推荐文章
原文: Useful functions to provide secure PHP application. 译文:有用的PHP安全函数. 安全是编程非常重要的一个方面. 在任何一种编程语言中,都提供了许多的函数或者模块来确保程序的安全性. 在现代网站应用中,经常要获取来自世界各地用户的输入,但是,我们都知道“永远不能相信那些用户输入的数据”.

PHP里10个鲜为人知但却非常有用的函数

- - 外刊IT评论网
PHP里有非常丰富的内置函数,很多我们都用过,但仍有很多的函数我们大部分人都不熟悉,可它们却十分的有用. 这篇文章里,我列举了一些鲜为人知但会让你眼睛一亮的PHP函数. 你有没有经历过需要知道两个单词有多大的不同的时候,这个函数就是来帮你解决这个问题的. 它能比较出两个字符串的不同程度. 这是一个在debug调试时非常有用的函数.

PHP导出excel

- syeye - scofield PHP开发-SEO SEM
最近做一个项目,其中涉及到了数据导成excel的功能. 后来使用了 开源的 PHPExcel  http://phpexcel.codeplex.com/ 目前最新版是1.7.6. PHPExcel 可以生成 .xls 和 .xlsx (office2007). 比如设置 excel的title,keywords,description.

PHP框架 Yaf

- Le - 开源中国社区最新软件
Yaf是一个C语言编写的PHP框架,Yaf 的特点: 用C语言开发的PHP框架, 相比原生的PHP, 几乎不会带来额外的性能开销. 所有的框架类, 不需要编译, 在PHP启动的时候加载, 并常驻内存. 更短的内存周转周期, 提高内存利用率, 降低内存占用率. 支持全局和局部两种加载规则, 方便类库共享.

PHP RFC: 让PHP的foreach支持list

- 三马 - 风雪之隅
本文地址: http://www.laruence.com/2011/07/13/2110.html. 上个月, 终于算加入了PHP developer team, 一直以来最大的障碍就是语言, 现在想起来, 当年真应该更加认真努力的去学习英语.. 得到的第一个任务是: 解决一个feature request, 请求在allow foreach($array as list($a,$b).

PHP开发宝典-PHP基础

- - CSDN博客推荐文章
.