GaRY's Blog

Beginning is always beautiful

FleaPHP默认上传类的一个隐患

随着各种开发框架的盛行,程序员也不愿意做那么多重复的事情了,开发,速度最重要.现在开发什么东西都讲究一个效率.
目前国内似乎还没有多少人对框架的安全性有多少研究.毕竟如果一个底层的编程框架出了问题,很多程序都将受到威胁.
我下了个国内现在很流行的php框架中一个:FleaPHP 1.0.70 beta.翻了翻他的FLEA/FLEA/Helper/FileUploader.php,这个是此框架默认的文件上传类.它有一个检查上传文件是否合法的函数:

    function check($allowExts = null, $maxSize = null)
    {
        
if (!$this->isSuccessed()) { return false; }
        
//允许上传的扩展名
        if ($allowExts) {
            
if (strpos($allowExts, ',')) {
                
$exts = explode(',', $allowExts);
            } 
elseif (strpos($allowExts, '/')) {
                
$exts = explode('/', $allowExts);
            } 
elseif (strpos($allowExts, '|')) {
                
$exts = explode('|', $allowExts);
            } 
else {
                
$exts = array($allowExts);
            }

            
$fileExt = strtolower($this->getExt());//获取扩展名
            $passed = false;
            
$exts = array_filter(array_map('trim', $exts), 'trim');
            
foreach ($exts as $ext) {
                
if (substr($ext, 0, 1== '.') {
                    
$ext = substr($ext, 1);
                }
                
if ($fileExt == strtolower($ext)) {
                    
$passed = true;
                    
break;
                }
            }
            
if (!$passed) {
                
return false;
            }
        }

        
if ($maxSize && $this->getSize() > $maxSize) {
            
return false;
        }

        
return true;
    }

再看getExt函数:

    function getExt()
    {
        
if ($this->isMoved()) {
            
return pathinfo($this->getNewPath(), PATHINFO_EXTENSION);
        } 
else {
            
return pathinfo($this->getFilename(), PATHINFO_EXTENSION);
        }
    }

继续跟踪php的pathinfo函数:

/* {{{ proto array pathinfo(string path[, int options])
   Returns information about a certain string 
*/

PHP_FUNCTION(pathinfo)
{
    zval 
*tmp;
    
char *path, *ret = NULL;
    
int path_len, have_basename;
    size_t ret_len;
    
long opt = PHP_PATHINFO_ALL;

    
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|l"&path, &path_len, &opt) == FAILURE) {
        
return;
    }


    have_basename 
= ((opt & PHP_PATHINFO_BASENAME) == PHP_PATHINFO_BASENAME);
    
    MAKE_STD_ZVAL(tmp);
    array_init(tmp);
    
    ......
    ......

    
if ((opt & PHP_PATHINFO_EXTENSION) == PHP_PATHINFO_EXTENSION) {
        
char *p;
        
int idx;

        
if (!have_basename) {
            php_basename(path, path_len, NULL, 
0&ret, &ret_len TSRMLS_CC);
        }


        p 
= zend_memrchr(ret, '.', ret_len);

        
if (p) {
            idx 
= p - ret;
            add_assoc_stringl(tmp, 
"extension", ret + idx + 1, ret_len - idx - 11);
        }

    }

    
    ......
    ......

    zval_ptr_dtor(
&tmp);
}

/* }}} */

到这里明白了,原来都只看文件名最后一个  "."  之后的部分作为文件的扩展名.那么如果根据apache的一个特性,我们可以使用多扩展名的方式上传php文件而绕过验证.(比如允许的扩展名里有rar,pdf等apache不认识但常见的类型,我们就可以上传shell.php.rar并得以执行)

当然这个只是个安全隐患而已.并不是所有用FleaPHP的程序都有这个问题.
就像superhei说的那样,关键在于看开发者如何去使用框架,不能太过依赖于框架提供的函数.而必须自己做些必要的前提验证.就能避免漏洞

posted on 2007-05-30 16:56 wofeiwo 阅读(950) 评论(0)  编辑 收藏 引用 网摘 所属分类: PHP security


只有注册用户登录后才能发表评论。
网站导航:

导航

<2023年2月>
2930311234
567891011
12131415161718
19202122232425
2627281234
567891011

统计

留言簿(10)

随笔分类(90)

随笔档案(61)

搜索

最新随笔

最新评论