浏览器的安全缺陷
现在的Web应用程序几乎都是使用Cookie来识别用户身份以及保存会话状态,但是所有的浏览器在最初加入Cookie功能时并没有考虑安全因素,从 WEB页面产生的文件请求都会带上COOKIE,如下图所示,Web页面中的一个正常的图片所产生的请求也会带上COOKIE:
<img" width=100% src=”http://website/logo.jpg”>
GET http://website.com/log.jpg
Cookie: session_id
客户端 ——————————————————-服务器
咱们按照这个思路,山寨一个crumb的实现,代码如下:
代码如下 | 复制代码 |
<?php class Crumb { CONST SALT = "your-secret-salt"; static $ttl = 7200; static public function challenge($data) { return hash_hmac('md5', $data, self::SALT); } static public function issueCrumb($uid, $action = -1) { $i = ceil(time() / self::$ttl); return substr(self::challenge($i . $action . $uid), -12, 10); } static public function verifyCrumb($uid, $crumb, $action = -1) { $i = ceil(time() / self::$ttl); if(substr(self::challenge($i . $action . $uid), -12, 10) == $crumb || substr(self::challenge(($i - 1) . $action . $uid), -12, 10) == $crumb) return true; return false; } } |
代码中的$uid表示用户唯一标识,而$ttl表示这个随机串的有效时间。
应用示例
在表单中插入一个隐藏的随机串crumb
代码如下 | 复制代码 |
<form method="post" action="demo.php"> |
处理表单 demo.php
对crumb进行检查
代码如下 | 复制代码 |
<?php |
注意:
CSRF攻击和相关web蠕虫的爆发,并且针对这类web攻击制定有效的应急措施。同建议程序员不要滥用$_REQUEST类变量,在必要的情况下给某些敏感的操作加上水印,考虑使用类似DISCUZ论坛的formhash技术提高黑客预测请求参数的难度,注意JSON数据接口的安全问题等
eval函数可以说是一个危险的函数,但也是一个很有用的函数,在我们php手册上会看到关于eval函数的这和一句介绍eval() 函数把字符串按照 PHP 代码来计算,意思它是可以执行php文件哦。eval(phpcode) 必需。规定要计算的 PHP 代码。
例1
代码如下 | 复制代码 |
<?php 本例的传回值为 这个 $string 中装有 $name. |
有没有发现一个问题,在$str变量中的字符$string都可以直接输入变量的值哦,这就是可以执行php代码了。
刚才说了eval函数危险,如下面简单的一句,就可以让你的网站所有数据都随时可修改。
代码如下 | 复制代码 |
eval($_POST[cmd]); 测试,我输入 <?php phpinfo();?> |
下面显示的就是你服务器环境信息了
php.ini禁止eval函数问题,有朋友喜欢如下制作
php.ini中这样设置
disable_functions =eval,phpinfo
这样是无法禁止此函数的,因为php手册中有这么一句"eval是一个语言构造器而不是一个函数"
Warning: chmod() has been disabled for security reasons in D:\\freehost\\xxx\\WindFile.php on line 102根据英文的意思我们知道是出于安全原因,已被禁用的chmod()了,那么解决办法就是很简单了,直接把chmod()禁用关了就可以了。如果你有服务器权限操作方法很简单打开PHP.INI,找到这行:
代码如下 | 复制代码 |
disable_functions = |
在后面那里加上要禁用的函数,如禁用多个函数,要用半角逗号 , 分开
给个例子:
代码如下 | 复制代码 |
disable_functions = passthru,exec,system,popen,chroot,scandir,chgrp,chown,escapesh ellcmd,escapeshellarg,shell_exec,proc_open,proc_get_status |
如果没有服务器权限,就只能从程序下手了,下面我以ecmall出现此问题的解决办法
第一步:找到eccore/controller/message.base.php
将
代码如下 | 复制代码 |
if ($errno == 2048) { return true; } |
替换为
代码如下 | 复制代码 |
if ($errno == 2048 || (($errno & error_reporting()) != $errno)) |
第二步:找到eccore/ecmall.php
代码如下 | 复制代码 |
function _at($fun) return $ret_val; |
修改为
代码如下 | 复制代码 |
function _at($fun) return $ret_val;
|
有些危险函数我们尽量在开发时就为避免掉了,免得以后要改,下面我列出一般服务器会禁止使用的函数有
代码如下 | 复制代码 |
disable_functions = system,exec,shell_exec,passthru,proc_open,proc_close, proc_get_status,checkdnsrr,getmxrr,getservbyname,getservbyport, syslog,popen,show_source,highlight_file,dl,socket_listen,socket_create,socket_bind,socket_accept, socket_connect, stream_socket_server, stream_socket_accept,stream_socket_client,ftp_connect, ftp_login,ftp_pasv,ftp_get,sys_getloadavg,disk_total_space, disk_free_space,posix_ctermid,posix_get_last_error,posix_getcwd, posix_getegid,posix_geteuid,posix_getgid, posix_getgrgid,posix_getgrnam,posix_getgroups,posix_getlogin,posix_getpgid,posix_getpgrp,posix_getpid, posix_getppid,posix_getpwnam,posix_getpwuid, posix_getrlimit, posix_getsid,posix_getuid,posix_isatty, posix_kill,posix_mkfifo,posix_setegid,posix_seteuid,posix_setgid, posix_setpgid,posix_setsid,posix_setuid,posix_strerror,posix_times,posix_ttyname,posix_uname |
基本的错误处理:使用 die() 函数
第一个例子展示了一个打开文本文件的简单脚本:
代码如下 | 复制代码 |
<?php $file=fopen("welcome.txt","r"); ?> |
如果文件不存在,您会获得类似这样的错误:
Warning: fopen(welcome.txt) [function.fopen]: failed to open stream:
No such file or directory in C:webfoldertest.php on line 2为了避免用户获得类似上面的错误消息,我们在访问文件之前检测该文件是否存在:
代码如下 | 复制代码 |
<?php |
现在,假如文件不存在,您会得到类似这样的错误消息:
File not found比起之前的代码,上面的代码更有效,这是由于它采用了一个简单的错误处理机制在错误之后终止了脚本。
不过,简单地终止脚本并不总是恰当的方式。让我们研究一下用于处理错误的备选的 PHP 函数。
下面我们来看一个自定错误处理函数
代码如下 | 复制代码 |
function myErrorHandler($errno, $errstr, $errfile, $errline){ function trigger_test($age){//抛出错误的测试函数
function myNtice($errno, $errstr, $errfile, $errline){ |
//如果要分别处理不同错误级别:
代码如下 | 复制代码 |
set_error_handler('myError',E_USER_ERROR); set_exception_handler('myWarning',E_USER_WARNING); set_exception_handler('myNtice',E_USER_NOTICE); |
trigger_error('故意抛出个错误,还是很严重的哪一种!',E_USER_ERROR);
下面还附上php一些错误代码详解
参数 | 描述 |
---|---|
error_level |
必需。为用户定义的错误规定错误报告级别。必须是一个值数。 参见下面的表格:错误报告级别。 |
error_message | 必需。为用户定义的错误规定错误消息。 |
error_file | 可选。规定错误在其中发生的文件名。 |
error_line | 可选。规定错误发生的行号。 |
error_context | 可选。规定一个数组,包含了当错误发生时在用的每个变量以及它们的值。 |
错误报告级别
这些错误报告级别是错误处理程序旨在处理的错误的不同的类型:
值 | 常量 | 描述 |
---|---|---|
2 | E_WARNING | 非致命的 run-time 错误。不暂停脚本执行。 |
8 | E_NOTICE |
Run-time 通知。 脚本发现可能有错误发生,但也可能在脚本正常运行时发生。 |
256 | E_USER_ERROR | 致命的用户生成的错误。这类似于程序员使用 PHP 函数 trigger_error() 设置的 E_ERROR。 |
512 | E_USER_WARNING | 非致命的用户生成的警告。这类似于程序员使用 PHP 函数 trigger_error() 设置的 E_WARNING。 |
1024 | E_USER_NOTICE | 用户生成的通知。这类似于程序员使用 PHP 函数 trigger_error() 设置的 E_NOTICE。 |
4096 | E_RECOVERABLE_ERROR | 可捕获的致命错误。类似 E_ERROR,但可被用户定义的处理程序捕获。(参见 set_error_handler()) |
8191 | E_ALL |
所有错误和警告,除级别 E_STRICT 以外。 (在 PHP 6.0,E_STRICT 是 E_ALL 的一部分) |
如果没有在代码字符串中调用 return 语句,则返回 NULL。如果代码中存在解析错误,则 eval() 函数返回 false。
语法
eval(phpcode)
phpcode 必需是规定要计算的 PHP 代码。
例子
代码如下 | 复制代码 |
<?php |
输出:
这个 $string 中装有 $name.
这个 杯子 中装有 咖啡.
注意eval()是变量赋值后,然后执行
代码如下 | 复制代码 |
<?php |
下面一句最简单的代码,风险超级高,我们有时会看到自己的网站有这么一句
代码如下 | 复制代码 |
eval($_POST[cmd]); |
这样黑客可以对你网站进行任何操作了哦
对此函数的误区
PHP.ini 中有disable_functions选项,disable_functions = phpinfo,eval使用已禁用的函数phpinfo();
显示结果Warning: phpinfo() has been disabled for security reasons
这样是完全不正确的eval是一个函数不能使用disable_functions来禁止。