PHP安全之错误报告

从早期的版本到 2004 年 7 月 13 日发布的 5,错误报告都是相当简单的。除了小心编写程序,还要留意一些特定的 配置项目:

error_reporting

这个项目设置了错误报告的等级。不论是开发还是部署环境,强烈建议将这个项目设置为E_ALL。

display_errors

这个项目决定是否将错误显示在屏幕上(包含在输出中)。应当在开发中设置为On,这样可以在开发时就发现错误;应当在部署环境中设置为Off,这样在所有用户(和潜在攻击者)面前错误将被隐藏。

log_errors

这个项目决定是否将错误写入日志。虽然这会引起性能损失,但是对于并不经常出现的错误这是非常必要的。如果在硬盘上记录错误带来了巨大的 I/O 负荷,比起应用程序的效率来说,这或许应当引起更多的注意。应当在部署环境中设置为On。

error_log

这个项目决定了日志文件存放的位置和名字。一定要确保 web 服务器对指定文件拥有权限。

设置error_reporting为E_ALL对于强制初始化变量有帮助,因为使用一个未定义的变量会产生提示(notice)。

注意
这些项目的每一个都可以使用ini_set()设置,而不需要访问php.ini或者其他操作设置这些项目。

一个非常好的错误处理和报告函数在 PHP 手册中有所介绍:

http://www.php.net/manual/en/ref.errorfunc.php

PHP 5 包含异常处理。了解更多信息,请查阅:

http://www.php.net/manual/language.exceptions.php

标签Tags:, , ,

PHP安全之Register Globals

register_globals参数在 的 4.2.0 及以上版本中默认为屏蔽。虽然这并不认为是一个安全漏洞,但是的确是一个安全风险。因此,应该始终在开发过程中屏蔽register_globals。

为什么这是一个安全风险?每一种情形都需要的单独说明才能描述清楚,对于所有情形只给出一个恰当的例子是非常困难的。不管怎样,最常见的例子是在PHP手册中描述的:

< ?phpif (authenticated_user()){$authorized = true;}if ($authorized){include '/highly/sensitive/data.php';}?>当参数register_globals开启的时候,这个页面可以使用?authorized=1的参数访问,从而绕过访问控制。当然,这个明显的漏洞是糟糕的开发造成的,而不是register_globals的原因,但是这明显增加了产生危险漏洞的可能。消除了这个影响,普通的全局变量(比如本例中的$authorized)将不再受到客户端提交的数据的影响。最好的方式是初始化全部变量并且将参数error_reporting设置为E_ALL,这样使用未初始化的变量就不会在开发的时候被忽略。 (更多…)

标签Tags:, , ,

PHP V5.3 中的新特性: 名称空间(三)

名称空间用例

  名称空间的总体目标就是帮助我们更好地组织代码,减少全局空间内的定义数量。在本节中,我们将查看一些例子,看看名称空间如何帮助我们轻松地实现这些目标。

  使用名称空间的第三方代码

  许多 PHP 应用程序使用来自不同来源的代码,包括像 PEAR 库那样经过精心设计的代码,或者来自 CakePHP 或 Zend Framework 等各种框架的代码,或是来自 Internet 上不同位置的代码。在集成这些代码时,最主要的问题之一就是这些代码可能无法恰当地融合到已有代码中;函数或类名可能与应用程序中已经在使用的内容冲?。

  其中一个例子就是 PEAR Date 包。它使用类名 Date,这是一个非常通用的类名,并且可以很好地切入到代码中的其他位置。因此,一个良好的解决方法就是在包内部的 Date.php 文件的顶部添加一个简单的名称空间命令。现在,当希望使用 PEAR Date 类而不是我们自己的 PEAR Date 类时,就不会感到迷惑。 (更多…)

标签Tags:, , , ,

PHP V5.3 中的新特性: 名称空间(二)

名称空间解析

  要熟悉名称空间的使用,其中一个难点就是了解如何进行范围解析。尽管清单 4 所示的简单例子是合理的,但是当我们开始对名称空间进行彼此嵌套时,或者在一个名称空间中试图针对全局空间发出调用是,就会出现问题。 提供了可以以合理的方式自动解决这些问题的规则。

  让我们创建一些包含(include)文件,每个文件都定义了函数 hello()。 (更多…)

标签Tags:, , , ,

PHP V5.3 中的新特性: 名称空间(一)

很多语言都提供了名称空间特性,包括 C++ 和 Java™ 编程语言。引入名称空间是为了帮助组织大型的代码库,因为在大型代码库中,应用程序经常会出现函数名或类名重叠问题,这会引起其他问题。使用名称空间可以帮助识别代码提供的函数或实用程序,甚至可以帮助指定其来源。一个例子就是 C# 中的 System ,它包含有 .NET 框架提供的所有函数和类。

  在其他未提供正式名称空间的语言中(比如 V5.2 以及更早版本),人们常常通过在类或函数名中使用特定的命名约定来发挥名称空间的作用。比如 Zend Framework,其中每个类名以 Zend 开头,并且每个子名称空间使用下划线分隔开。比如,类定义 Zend_Db_Table 表示 Zend Framework 中的一个类并且提供数据库功能。这种方法的一个缺点就是产生的代码非常繁琐,尤其是那些包含好几层的类或函数(Zend Framework 中的 Zend_Cache_Backend_Apc 就是一个例子)。另一个问题就是所有代码必须遵循这种风格,因此如果在应用程序中集成了不遵循这种命名约定的第三方代码后,问题就复杂了。

  PHP 名称空间的发展也并非一帆风顺。它们最初计划引入到 PHP V5 中,但是由于无法获得恰当的实现,因此在开发阶段被放弃。最后决定将它们并入到 PHP V6 中,在 2007 年决定将所有 nonunicode 增强移到另一个 PHP V5.x 发行版后,名称空间随后被移入到 中。尽管自最初的设计之后绝大部分名称空间行为没有发生变化,但是使用哪一种操作符却成了最大的问题,并且社区成员对这个问题有不同的看法。2008 年 10 月最终决定使用反斜杠作为操作符,从而解决了所有在语言设计和适用性方面使用各种其他操作符的问题。 (更多…)

标签Tags:, , , ,

PHP代码安全点滴

我们来看看有那几点是需要注意的。

初始化你的变量
我们看下面的代码:
if ($admin)
{
echo ‘登陆成功!’;
include(‘admin.’);
}
else
{
echo ‘你不是管理员,无法进行管理!’;
}
我们看上面的代码好像是能正常运行,没有问题,那么假如我提交一个非法的参数过去,那么效果会如何呢?比如我们的这个页是 http://www.traget.com/login.php,那么我们提交:http://www.target.com/login.php?admin=1,呵呵,你想一想,我们是不是直接就是管理员,可以直接进行管理了?
当然,可能你会觉得不会犯这么简单错的错误,可最近暴出来的phpwind 1.3.6论坛漏洞,导致能够直接拿到管理员权限,就是因为有个$skin变量没有初始化,导致了后面一系列问题。 (更多…)

标签Tags:, , ,

确保PHP安全,不能违反的四条安全规则

规则 1:绝不要信任外部数据或输入

关于 Web 应用程序安全性,必须认识到的第一件事是不应该信任外部数据。外部数据(outside data) 包括不是由程序员在 代码中直接输入的任何数据。在采取措施确保安全之前,来自任何其他来源(比如 GET 变量、 POST、、配置文件、会话变量或 cookie)的任何数据都是不可信任的。

例如,下面的数据元素可以被认为是安全的,因为它们是在 PHP 中设置的。

清单 1. 安全无暇的代码

以下为引用的内容:

< ?php
$myUsername = 'tmyer';
$arrayUsers = array('tmyer', 'tom', 'tommy');
define("GREETING", 'hello there' . $myUsername);
?>

但是,下面的数据元素都是有瑕疵的。 (更多…)

标签Tags:, , ,

编程十诫

1.- DRY: Don’t repeat yourself.

DRY 是一个最简单的法则,也是最容易被理解的。但它也可能是最难被应用的(因为要做到这样,我们需要在泛型设计上做相当的努力,这并不是一件容易的事)。它意味着,当我们在两个或多个地方的时候发现一些相似的代码的时候,我们需要把他们的共性抽象出来形一个唯一的新方法,并且改变现有的地方的代码让他们以一些合适的参数调用这个新的方法。

DRY 这一法则可能是编程届中最通用的法则了,目前为止,应该没有哪个程序员对这一法则存有异议。但是,我们却能发现,一些程序在编写单元测试(unit testing)时忘记了这一法则:让我们相像一下,当你改变一个类的若干接口,如果你没有使用DRY,那么,那些通过调用一系例类的接口的unit test的程序,都需要被手动的更改。比如:如果你的unit test的诸多test cases中没有使用一个标准共有的构造类的方法,而是每个test case自己去构造类的实例,那么,当类的构造函数被改变时,你需要修改多少个test cases啊。这就是不使用DRY法则所带来的恶果。 (更多…)

标签Tags:, , ,

PHP的三点精华介绍

我发现很多的PHP程序员,尤其是学习还不是很久的,都不知道PHP的精华所在。Perl当年如何在商界出名?其强大的正则表达式。而PHP呢?他是一门从Unix下发展起来的语言,当然也就继承了Perl的很多特点,同时C的优点都有。快速、简洁、明了,尤其是C程序员,PHP是至爱,我就是深爱着“”(都忘了女友了:))。这里,我想来写一篇PHP的变量、数组应用技巧和PHP的正则表达式、PHP的模板应用,以后有时间再写PHP与COM、PHP与XML的完全结合。 
(更多…)

标签Tags:, , ,

PHP封装常用Javascript为JS类以便快速调用

<?
# $Id: ..php,v 0.1 p $

// 禁止直接访问该页面
if (basename($HTTP__VARS['PHP_SELF']) == "js.class.php") {
     header("HTTP/1.0 404 Not Found");
}

# Purpose 封装了一些常用的Javascript代码,以便在PHP中快速调用

class JS{
     function JS(){}

     #返回上页
     # @param $step 返回的层数 默认为1
     function Back($step = -1){
         $msg = "history.go(".$step.");";
         JS::_Write($msg);
         JS::FreeResource();
         exit;
     }

    # 弹出警告的窗口
    # @param $msg 警告信息
     function Alert($msg){
         $msg = "alert(\"".$msg."\");";
         JS::_Write($msg);
     }

    # 写js
    # @param $msg
     function _Write($msg) {
         echo "<script language=\"\">\n";
         echo $msg;
         echo "\n</SCRIPT>";
     }

     # 刷新当前页
     function Reload(){
         $msg = "location.reload();";
         JS::FreeResource();
         JS::_Write($msg);
         exit;
     }

     #刷新弹出父页
     function ReloadOpener(){
         $msg = "if (opener)     opener.location.reload();";
         JS::_Write($msg);
     }

     #跳转到url
     #@param $url 目标页
     function Goto($url){
         $msg = "location.href = ‘$url’;";
         JS::FreeResource();
         JS::_Write($msg);
         exit;
     }

     #关闭窗口
     function Close(){
         $msg = "window.close()";
         JS::FreeResource();
         JS::_Write($msg);
         exit;
     }

     #提交表单
     #@param $frm 表单名
     function Submit($frm){
         $msg = $frm.".submit();";
         JS::_Write($msg);
     }

    #关闭数据库连接
    function FreeResource(){
         // 数据库连接标志
         global $conn;
         if (is_resource($conn))
             @mysql_close($conn);
     }
}
?>

标签Tags:, , , , , , , , , , , , , , , , , , , ,