当前位置: 首页 > 图文教程 > 网络编程 > PHP > PHP泛安全

PHP
随时给自己贴的图片加文字的php代码
一个可分页的基于文本的PHP留言板源码
一个简单的PHP投票程序源码
一个模仿oso的php论坛程序(之一)
一个模仿oso的php论坛程序源码(之二)
一个模仿oso的php论坛程序源码(之三)
dedecms 制作模板中使用的全局标记图文教程
一个简单的PHP&MYSQL留言板源码
PHP实现多服务器session共享之NFS共享的方法
随时给自己贴的图片加文字的php水印
php环境配置 php5 MySQL5 apache2 phpmyadmin安装与配置图文教程
火车头采集器3.0采集图文教程
用PHP生成静态HTML速度快类库
Discuz!插件:自动隐藏帖子
php中判断一个字符串包含另一个字符串的方法
dedecms后台验证码总提示错误的解决方法
加速XP搜索功能堪比vista
人尽可用的Windows技巧小贴士之下篇
PHP+Ajax 网站SEO查询工具 提供代码
用PHP实现的生成静态HTML速度快类库

PHP泛安全


出处:互联网   整理: 软晨网(RuanChen.com)   发布: 2009-11-03   浏览: 125 ::
收藏到网摘: n/a

/*---------------
*Author:xy7
*Data:2006/11/1
*---------------
*/


如今基于PHP的WEB程序是越来越安全了,php.ini默认时的 magic_quotes_gpc=on就在初始安全性上提高了一个档次.很多程序在接受到用户的输入时都会提前判断一下 get_magic_quotes_gpc() 即使这个开关没有开就马上addslashes()函数跟上进行转义,所以想在PHP程序中找到一个类似与以前ASP注入那样的漏洞是比较不容易的.
对于PHP的跨站其实也很好防范,用 htmlentities() 就可以了,不过当处理XML文件时采用这个函数可能会出现些问题,只需手工转换下那5个元字符就可以了。举个例子,以前写过篇文章关于XML文件隐患的,其实就是CDATA部件的问题,现在比较流行的说法是AJAX hacking,大概说下,看看以下代码:
if ($rssid == 0 OR $rssid == 7) {
} elseif (!empty($stmt)) {
    $dbinfo =& $db->getResultSet($stmt, array('pageSize'=>$pagesize));
    if ($dbinfo === false) {
        $msginfo = str_replace(']]>', ']]>', $lang['tpl.str0']);
        $TPL_items .= <<<EOT
        <item>
            <title>{$msginfo}</title>
            <link>{$fsetting['forumurl']}</link>
            <author>{$fsetting['forumname']}</author>
            <pubDate>{$datenow}</pubDate>
            <description><![CDATA[{$msginfo}]]></description>
        </item>
EOT;
$msginfo是用户提交的,然后被程序写进RSS里以用来聚合,如果$msginfo的值为<sciript>alert('loveshell')</script>时,RSS聚合解析后会原样输出,如果为]]><sciript>alert('loveshell')</script>时,就可以跨站了,看看他的过滤:
if ($dbinfo === false) {
        $msginfo = str_replace(']]>', ']]>', $lang['tpl.str0']);
很好意识到了这点,可是这句呢<title>{$msginfo}</title>,意识到问题所在很关键,重要的是要理解问题.

可是还是有很多会被程序员疏忽的地方,这是安全意识的问题,对于用户的任何输入,在写程序时脑子里都要提前做个思考:用户的输入是什么类型的?用户会有哪些输入方式?怎么处理用户的错误和非常规输入?
PHP的安全还体现在Safe Mode 和openbase-dir上.即使这样基于PHP底层的一些漏洞还是会直接影响到这两个非常重要的安全选项.举个例子:
比如error_log() Safe Mode Bypass
看他的语法:bool error_log ( string message [, int message_type [, string destination [, string extra_headers]]] )
输出错误信息到一个文件,可以这样写
<?
error_log("<? phpinfo();?>", 3, "test.php");
?>
运行在safe_mode关闭的情况下,直接访问test.php就可以看到phpinfo了,当safe_mode开的时候就会报错,再这样写:
<?
error_log("<? phpinfo();?>", 3, "prefix://../../test.php");
?>可以看到phpinfo又被执行了
看下漏洞代码:
PHPAPI int _php_error_log(int opt_err, char *message, char *opt, char *headers TSRMLS_DC)

{

php_stream *stream = NULL;

switch (opt_err) {

case 1: /*send an email */

{

#if HAVE_SENDMAIL

if (!php_mail(opt, "PHP error_log message", message, headers, NULL TSRMLS_CC)) {


return FAILURE;

}

php_error_docref(NULL TSRMLS_CC, E_WARNING, "Mail option not available!");

return FAILURE;

}

break;

case 2: /*send to an address */

php_error_docref(NULL TSRMLS_CC, E_WARNING, "TCP/IP option not available!");

return FAILURE;

break;

case 3: /*save to a file */

stream = php_stream_open_wrapper(opt, "a", IGNORE_URL | ENFORCE_SAFE_MODE | REPORT_ERRORS, NULL);

if (!stream)

return FAILURE;

php_stream_write(stream, message, strlen(message));

php_stream_close(stream);

break;

default:

php_log_err(message TSRMLS_CC);

break;

}

return SUCCESS;

}
可以看到error_log函数的核心就是 php_stream_open_wrapper()函数,问题也就出在保存错误信息