PHP数据过滤函数与方法示例

1、php提交数据过滤的基本原则 

1)提交变量进数据库时,我们必须使用addslashes()进行过滤,像我们的注入问题,一个addslashes()也就搞定了。其实在涉及到变量取值时,intval()函数对字符串的过滤也是个不错的选择。

2)在php.ini中开启magic_quotes_gpc和magic_quotes_runtime。magic_quotes_gpc可以把get,post,cookie里的引号变为斜杠。magic_quotes_runtime对于进出数据库的数据可以起到格式话的作用。其实,早在以前注入很疯狂时,这个参数就很流行了。

3)在使用系统函数时,必须使用escapeshellarg(),escapeshellcmd()参数去过滤,这样你也就可以放心的使用系统函数。

4)对于跨站,strip_tags(),htmlspecialchars()两个参数都不错,对于用户提交的的带有html和php的标记都将进行转换。比如尖括号"<"就将转化为 "<"这样无害的字符。

 代码如下 复制代码
$new = htmlspecialchars("<a href='test'>Test</a>", ENT_QUOTES);
strip_tags($text,);

5)对于相关函数的过滤,就像先前的include(),unlink,fopen()等等,只要你把你所要执行操作的变量指定好或者对相关字符过滤严密,我想这样也就无懈可击了。

2、PHP简单的数据过滤

1)入库:  trim($str),addslashes($str)
2)出库:  stripslashes($str)
3)显示:  htmlspecialchars(nl2br($str))

看下面的例子以便进一步讨论dispatch.php脚本:

 代码如下 复制代码

<?php

/* 全局安全处理 */

switch ($_GET['task'])
{
case 'print_form':
include '/inc/presentation/form.inc';
break;

case 'process_form':
$form_valid = false;
include '/inc/logic/process.inc';
if ($form_valid)
{
include '/inc/presentation/end.inc';
}
else
{
include '/inc/presentation/form.inc';
}
break;

default:
include '/inc/presentation/index.inc';
break;
}

?>

如果这是唯一的可公开访问到的 PHP 脚本,则可以确信的一点是这个程序的设计可以确保在最开始的全局安全处理无法被绕过。同时也让开发者容易看到特定任务的控制流程。例如,不需要浏览整个代码就可以容易的知道:当$form_valid为true时,end.inc是唯一显示给用户的;由于它在process.inc被包含之前,并刚刚初始化为false,可以确定的是process.inc的内部逻辑会将设置它为true;否则表单将再次显示(可能会显示相关的错误信息)。
注意
如果你使用目录定向文件,如index.php(代替dispatch.php),你可以像这样使用 URL 地址:http://example.org/?task=print_form。
你还可以使用 ApacheForceType重定向或者mod_rewrite来调整 URL 地址:http://example.org/app/print-form。
包含方法
另外一种方式是使用单独一个模块,这个模块负责所有的安全处理。这个模块被包含在所有公开的 PHP 脚本的最前端(或者非常靠前的部分)。参考下面的脚本security.inc

 代码如下 复制代码

<?php

switch ($_POST['form'])
{
case 'login':
$allowed = array();
$allowed[] = 'form';
$allowed[] = 'username';
$allowed[] = 'password';

$sent = array_keys($_POST);

if ($allowed == $sent)
{
include '/inc/logic/process.inc';
}

break;
}

?>

在本例中,每个提交过来的表单都认为应当含有form这个唯一验证值,并且security.inc独立处理表单中0需要过滤的数据。实现这个要求的 HTML 表单如下所示:

 代码如下 复制代码
<form action="/receive.php" method="POST">
<input type="hidden" name="form" value="login" />
<p>Username:
<input type="text" name="username" /></p>
<p>Password:
<input type="password" name="password" /></p>
<input type="submit" />
</form>

叫做$allowed的数组用来检验哪个表单变量是允许的, 这个列表在表单被处理前应当是一致的。流程控制决定要执行什么,而process.inc是真正过滤后的数据到达的地方。
注意
确保security.inc总是被包含在每个脚本的最开始的位置比较好的方法是使用auto_prepend_file设置。
过滤的例子
建立白名单对于数据过滤是非常重要的。由于不可能对每一种可能遇到的表单数据都给出例子,部分例子可以帮助你对此有一个大体的了解。
下面的代码对邮件地址进行了验证:

 代码如下 复制代码

<?php

$clean = array();

$email_pattern = '/^[^@s<&>]+@([-a-z0-9]+.)+[a-z]{2,}$/i';

if (preg_match($email_pattern, $_POST['email']))
{
$clean['email'] = $_POST['email'];
}

?>

下面的代码确保了$_POST['color']的内容是red,green,或者blue:

 代码如下 复制代码

<?php

$clean = array();

switch ($_POST['color'])
{
case 'red':
case 'green':
case 'blue':
$clean['color'] = $_POST['color'];
break;
}

?>

下面的代码确保$_POST['num']是一个整数(integer):

 代码如下 复制代码

<?php

$clean = array();

if ($_POST['num'] == strval(intval($_POST['num'])))
{
$clean['num'] = $_POST['num'];
}

?>

下面的代码确保$_POST['num']是一个浮点数(float):

 代码如下 复制代码

<?php

$clean = array();

if ($_POST['num'] == strval(floatval($_POST['num'])))
{
$clean['num'] = $_POST['num'];
}

?>

名字转换
之前每个例子都使用了数组$clean。对于开发人员判断数据是否有潜在的威胁这是一个很好的习惯。 永远不要在对数据验证后还将其保存在$_POST或者$_GET中,作为开发人员对超级全局数组中保存的数据总是应当保持充分的怀疑。
需要补充的是,使用$clean可以帮助思考还有什么没有被过滤,这更类似一个白名单的作用。可以提升安全的等级。
如果仅仅将验证过的数据保存在$clean,在数据验证上仅存的风险是你所引用的数组元素不存在,而不是未过滤的危险数据。
时机
一旦 PHP 脚本开始执行,则意味着 HTTP 请求已经全部结束。此时,用户便没有机会向脚本发送数据。因此,没有数据可以被输入到脚本中(甚至register_globals被开启的情况下)。这就是为什么初始化变量是非常好的习惯。

防注入

 代码如下 复制代码

<?PHP
//PHP整站防注入程序,需要在公共文件中require_once本文件
//判断magic_quotes_gpc状态
if (@get_magic_quotes_gpc ()) {
$_GET = sec ( $_GET );
$_POST = sec ( $_POST );
$_COOKIE = sec ( $_COOKIE );
$_FILES = sec ( $_FILES );
}
$_SERVER = sec ( $_SERVER );
function sec(&$array) {
//如果是数组,遍历数组,递归调用
if (is_array ( $array )) {
foreach ( $array as $k => $v ) {
$array [$k] = sec ( $v );
}
} else if (is_string ( $array )) {
//使用addslashes函数来处理
$array = addslashes ( $array );
} else if (is_numeric ( $array )) {
$array = intval ( $array );
}
return $array;
}
//整型过滤函数
function num_check($id) {
if (! $id) {
die ( '参数不能为空!' );
} //是否为空的判断
else if (inject_check ( $id )) {
die ( '非法参数' );
} //注入判断
else if (! is_numetic ( $id )) {
die ( '非法参数' );
}
//数字判断
$id = intval ( $id );
//整型化
return $id;
}
//字符过滤函数
function str_check($str) {
if (inject_check ( $str )) {
die ( '非法参数' );
}
//注入判断
$str = htmlspecialchars ( $str );
//转换html
return $str;
}
function search_check($str) {
$str = str_replace ( "_", "_", $str );
//把"_"过滤掉
$str = str_replace ( "%", "%", $str );
//把"%"过滤掉
$str = htmlspecialchars ( $str );
//转换html
return $str;
}
//表单过滤函数
function post_check($str, $min, $max) {
if (isset ( $min ) && strlen ( $str ) < $min) {
die ( '最少$min字节' );
} else if (isset ( $max ) && strlen ( $str ) > $max) {
die ( '最多$max字节' );
}
return stripslashes_array ( $str );
}
//防注入函数
function inject_check($sql_str) {
return eregi ( 'select|inert|update|delete|'|/*|*|../|./|UNION|into|load_file|outfile', $sql_str );
// www.111cn.net 进行过滤,防注入
}
function stripslashes_array(&$array) {
if (is_array ( $array )) {
foreach ( $array as $k => $v ) {
$array [$k] = stripslashes_array ( $v );
}
} else if (is_string ( $array )) {
$array = stripslashes ( $array );
}
return $array;
}
?>

时间: 2024-11-22 17:22:25

PHP数据过滤函数与方法示例的相关文章

PHP数据过滤函数

  1.php提交数据过滤的基本原则 1)提交变量进数据库时,我们必须使用addslashes()进行过滤,像我们的注入问题,一个addslashes()也就搞定了.其实在涉及到变量取值时,intval()函数对字符串的过滤也是个不错的选择. 2)在php.ini中开启magic_quotes_gpc和magic_quotes_runtime.magic_quotes_gpc可以把get,post,cookie里的引号变为斜杠.magic_quotes_runtime对于进出数据库的数据可以起到

excel连接函数使用方法示例

CONCATENATE函数是什么 语法 CONCATENATE (text1,text2,...) Text1, text2, ... 为 1 到 30 个将要合并成单个文本项的文本项.这些文本项可以为文本字符串.数字或对单个单元格的引用. 说明 也可以用 &(和号)运算符代替函数 CONCATENATE 实现文本项的合并. 用&运算符可以代替CONCATENATE函数实现文本项的合并.如公式="张"&"军"的结果为"张军"

windows.moveBy()函数使用方法示例

window|函数|示例 (一).示例图片效果 (二).代码 <html><head><title>window.setTimeout()函数</title><script laguage="javascript"><!--function showtime(){mytime=new Date();mytime=mytime.getHours()+":"+mytime.getMinutes()+&qu

php POST GET 数据过滤函数

foreach(array('_GET','_POST') as $_request) {  foreach($$_request as $_key => $_value) {   if ($_key{0} != '_') {    if (IS_GPC) {     $_value = s_array($_value);    }    $$_key = $_value;   }  } } function s_array(&$array) {  if (is_array($array))

Lua中访问table里函数的方法示例_Lua

看例子代码: 复制代码 代码如下: do  table_ = {   a = 1,   foo = function(i)      return i     end  }  print(table_.foo(1)) end

PHP简单字符串过滤方法示例_php技巧

本文实例讲述了PHP简单字符串过滤方法.分享给大家供大家参考,具体如下: <!DOCTYPE html> <html lang="zh-cn"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1,maximum-scale=1, user-s

PHP数据过滤的方法_php技巧

在指南的开始,我们说过数据过滤在任何语言.任何平台上都是WEB应用安全的基石.这包含检验输入到应用的数据以及从应用输出的数据,而一个好的软件设计可以帮助开发人员做到:确保数据过滤无法被绕过,确保不合法的信息不会影响合法的信息,并且识别数据的来源.关于如何确保数据过滤无法被绕过有各种各样的观点,而其中的两种观点比其他更加通用并可提供更高级别的保障.调度方法这种方法是用一个单一的 php 脚本调度(通过 URL).其他任何操作在必要的时候使用include或require包含进来.这种方法一般需要每

数据访问函数库的使用方法(一)——添加修改数据

由于这个类库是需要实例化的,如果每一次都要实例化,然后用完了在销毁,无形中就多了不少的代 码,而且很容易忘记销毁实例. 同时在用户的一次访问的过程中不断地实例化.销毁,也是比较浪费资源的. 所以我建立了一个基类,在基类里面同意获得实例.统一销毁实例,这样在编码的时候就不用考虑有 没有实例化,也不用担心是否销毁实例了, 另外用起来(使用方式)也和静态类的使用方式很像了. 基类里的代码: (ps:我习惯在.aspx.cs里面直接调用 数据访问函数库,所以这个基类是继承 System.Web.UI.P

Flash MX本地保存数据的二种方法

数据 谈到计算机操作,往往就不了数据操作,最基本的数据操作就是读取和保存数据.Flash程序很多时候也会用到数据操作,比如说载入外部文件就是读取数据.然而Flash保存数据的能力是很有限的.Flash 5时我们还可以用fscommond来本地保存外部文本文件,到了FlashMX时代,出于对安全因素的考虑,Micromedia取消了这个功能. 那是不是我们就无法用Flash MX保存数据了呢?回答是否定的,这里我就系统给大家介绍用Flash MX本地保存外部数据的三种方法. 方法一:使用MMsav