PHP程序中的常见漏洞
[库文件]
正如我们前面讨论的那样,include()和require()主要是为了支持代码库,因为我们一样平常是把一些经常利用的函数放到一个独立的文件中,这个独立的文件就是代码库,当必要利用其中的函数时,我们只要把这个代码库包罗到以后的文件中就可以了。
最初,人们开发和发布PHP步伐的时候,为了区别代码库和主步伐代码,一样平常是为代码库文件设置一个“.inc”的扩展名,但是他们很快发明这是一个错误,因为如许的文件无法被PHP表明器正确剖析为PHP代码。如果我们直接请求服务器上的这种文件时,我们就会得到该文件的源代码,这是因为当把PHP作为Apache的模块利用时,PHP表明器是凭据文件的扩展名来决议能否剖析为PHP代码的。扩展名是站点管理员指定的,一样平常是“.php”, “.php3”和“.php4”。如果重要的配置数据被包罗在没有符合的扩展名的PHP文件中,那么远程攻击者很容易得到这些信息。
最简单的解决方法就是给每个文件都指定一个PHP文件的扩展名,如许可以很好的防备泄漏源代码的问题,但是又孕育发生了新的问题,经过请求这个文件,攻击者大概使本该在上下文情况中运行的代码独立运行,这大概招致前面讨论的全部攻击。
上面是一个很明显的例子:
In main.php:
$libDir = "/libdir";
$langDir = "$libdir/languages";
...
include("$libdir/loadlanguage.php":
?>
In libdir/loadlanguage.php:
...
include("$langDir/$userLang");
?>
当“libdir/loadlanguage.php”被“main.php”挪用时是相当安全的,但是因为“libdir/loadlanguage”具有“.php”的扩展名,因此远程攻击者可以直接请求这个文件,并且可以恣意指定“$langDir”和“$userLang”的值。
[Session文件]
PHP 4或更新的版本提供了对sessions的支持,它的主要作用是在PHP步伐中生存页与页之间的状态信息。比方,当一个用户登岸进入网站,他登岸了这个事实以及谁登岸进入这个网站都被生存在session中,当他在网站中随处欣赏时,所有的PHP代码都可以获得这些状态信息。
事实上,当一个session启动时(现实上是在配置文件中设置为在第一次请求时自动启动),就会天生一个随机的“session id”,如果远程欣赏器总是在发送请求时提交这个“session id”的话,session就会不停连结。这经过Cookie很容易完成,也可以经过在每页提交一个表单变量(包罗“session id”)来完成。PHP步伐可以用session注册一个特殊的变量,它的值会在每个PHP脚本结束后存在session文件中,也会在每个PHP脚本开端前加载到变量中。上面是一个简单的例子:
session_destroy(); // Kill any data currently in the session
$session_auth = "shaun";
session_register("session_auth"); // Register $session_auth as a session variable
?>
新版本的PHP都市自动把“$session_auth”的值设置为“shaun”,如果它们被修改的话,以后的脚本都市自动接受修改后的值,这对无状态的Web来说的确是种很不错的东西,但是我们也应该警惕。
一个很明显的问题就是确保变量的确来自session,比方,给定上面的代码,如果后续的脚本是上面如许的话:
if (!empty($session_auth))
// Grant access to site here
?>
上面的代码假定如果“$session_auth”被置位的话,就是从session,而不是从用户输出来置位的,如果攻击者经过表单输出来置位的话,他就可以获得对站点的访问权。注意攻击者必须在session注册该变量之前利用这种攻击方法,一旦变量被放进了session,就会覆盖任何表单输出。
Session数据一样平常是生存在文件中(位置是可配置的,一样平常是“/tmp”),文件名一样平常是雷同“sess_
Session机制也为攻击者把本身的输出生存在远程系统的文件中提供了另一个方便的地方,对于上面的例子来说,攻击者必要在远程系统安排一个包罗PHP代码的文件,如果不克不及利用文件上载做到的话,他通常会利用session为一个变量按照本身的意愿赋一个值,然后猜测session文件的位置,而他知道文件名是“php
别的,攻击者可以恣意指定“session id”(比方“hello”),然后用这个“session id”创建一个session文件(比方“/tmp/sess_hello”),但是“session id”只能是字母和数字组合。
[数据范例]
PHP具有比较松散的数据范例,变量的范例依赖于它们所处的上下文情况。比方:“$hello”开端是字符串变量,值为“”,但是在求值时,就酿成了整形变量“0”,这有时大概会招致一些意想不到的效果。如果“$hello”的值为“000”照旧为“0”是不同的,empty()返回的效果也不会为真。
PHP中的数组是关联数组,也就是说,数组的索引是字符串型的。这意味着“$hello["000"]”和“$hello[0]”也是不同的。
开发步伐的时候应该仔细地思量上面的问题,比方,我们不应该在一个地方测试某个变量能否为“0”,而在别的的地方利用empty()来验证。
[容易出错的函数]
我们在分析PHP步伐中的毛病时,如果能够拿到源代码的话,那么一份容易出错的函数列表则是我们十分必要的。如果我们能够远程改变这些函数的参数的话,那么我们就很大概发明其中的毛病。上面是一份比较详细的容易出错的函数列表:
require():读取指定文件的内容并且作为PHP代码表明
include():同上
eval():把给定的字符串作为PHP代码实行
preg_replace():当与“/e”开关一起利用时,更换字符串将被表明为PHP代码
<命令实行>
exec():实行指定的命令,返回实行效果的最后一行
passthru():实行指定数令,返回所有用果到客户欣赏器
``:实行指定数令,返回所有用果到一个数组
system():同passthru(),但是不处理二进制数据
popen():实行指定的命令,把输出或输出连接到PHP文件形貌符
<文件泄漏>
fopen():翻开文件,并对应一个PHP文件形貌符
readfile():读取文件的内容,然后输出到客户欣赏器
file():把整个文件内容读到一个数组中
译者注:实在这份列表还不是很全,好比“mail()”等命令也大概实行命令,所以必要本身增补一下。
[如何增强PHP的安全性]
我在上面先容的所有攻击对于缺省安装的PHP 4都可以很好的完成,但是我曾经反复了很多次,PHP的配置十分灵活,经过配置一些PHP选项,我们完全大概抵挡其中的一些攻击。上面我按照完成的难度对一些配置举行了分类:
*低难度
**中低难度
***中高难度
****高难度
上面的分类只是小我私家的看法,但是我可以包管,如果你利用了PHP提供的所有选项的话,那么你的PHP将是很安全的,即使是第三方的代码也是云云,因为其中很多功效曾经不克不及利用。
**** 设置“register_globals”为“off”
这个选项会禁止PHP为用户输出创建全局变量,也就是说,如果用户提交表单变量“hello”,PHP不会创建“$ hello”,而只会创建“HTTP_GET/POST_VARS[’hello’]”。这是PHP中一个极其重要的选项,封闭这个选项,会给编程带来很大的未便。
*** 设置“safe_mode”为“on”
翻开这个选项,会增加如下限制:
1. 限制哪个命令可以被实行
2. 限制哪个函数可以被利用
3. 基于脚本所有权和目标文件所有权的文件访问限制
4. 禁止文件上载功效
这对于ISP来说是一个巨大的选项,同时它也能极大地革新PHP的安全性。
** 设置“open_basedir”
这个选项可以禁止指定目录之外的文件操纵,有用地消弭了本地文件大概是远程文件被include()的攻击,但是仍必要注意文件上载和session文件的攻击。
** 设置“display_errors”为“off”,设置“log_errors”为“on”
这个选项禁止把错误信息表现在网页中,而是记载到日志文件中,这可以有用的抵挡攻击者对目标脚本中函数的探测。
* 设置“allow_url_fopen”为“off”
这个选项可以禁止远程文件功效,尽力保举!
- 文章作者: 福州军威计算机技术有限公司
军威网络是福州最专业的电脑维修公司,专业承接福州电脑维修、上门维修、IT外包、企业电脑包年维护、局域网网络布线、网吧承包等相关维修服务。
版权声明:原创作品,允许转载,转载时请务必以超链接形式标明文章原始出处 、作者信息和声明。否则将追究法律责任。
TAG:
评论加载中...
|