1. php教程 配置文件 php.ini
    中的 magic_quotes_gpc 选项未有展开,被置为 off 2.
    开荒者没有对数据类型进行检讨和转义
  1. php 配置文件 php.ini 中的 magic_quotes_gpc 选项未有张开,被置为
    off
      2. 开采者未有对数据类型实行检讨和转义
      可是事实上,第二点最为关键。我觉着, 对用户输入的数据类型实行检讨,向
    mysql教程
    提交正确的数据类型,那应该是贰个 web
    技士最最大旨的素质。但现实中,日常有很多小白式的 web 开垦者忘了那一点,
    进而导致后门大开。
      为啥说第二点最为根本?因为只要未有第二点的管教,magic_quotes_gpc
    选项,不论为 on,依旧为 off,皆有望引发 sql
    注入攻击。上边来看一下本领实现:
     一. magic_quotes_gpc = off 时的注入攻击
      magic_quotes_gpc = off 是 php 中一种拾壹分不安全的选项。新本子的 php
    已经将暗中认可的值改为了 on。但仍有一定多的服务器的挑选为
    off。终究,再古董的服务器也会有人用的。
      当magic_quotes_gpc = on 时,它会将付出的变量中兼有的
    ‘(单引号)、”(双号号)、(反斜线)、空白字符,都为在后边自动抬高 。上面是
    php 的官方证实:

唯独事实上,第二点最为重大。笔者感到, 对用户输入的数据类型举办反省,向
mysql教程
提交准确的数据类型,那应当是贰个 web
程序猿最最宗旨的素质。但现实中,日常有数不胜数小白式的 web 开采者忘了这一点,
进而导致后门大开。

复制代码 代码如下:
magic_quotes_gpc boolean

怎么说第二点最为根本?因为只要未有第二点的承接保险,magic_quotes_gpc
选项,不论为 on,照旧为 off,都有望引发 sql
注入攻击。上面来看一下技艺达成:

sets the magic_quotes state for gpc
(get/post/cookie)
operations. when magic_quotes are on, all ‘ (single-quote), ” (double
quote), (backslash) and nul’s are escaped with a backslash automatically

一. magic_quotes_gpc = off 时的注入攻击

万一未有转义,即 off
情状下,就可以让攻击者有隙可乘。以下列测量检验脚本为例:
复制代码 代码如下:

magic_quotes_gpc = off 是 php 中一种非凡不安全的选项。新本子的 php
已经将暗中认可的值改为了 on。但仍有一定多的服务器的精选为
off。毕竟,再古董的服务器也会有人用的。

<?
if ( isset($_post[“f_login”] ) )
{
// 连接数据库教程…
// …代码略…

// 检查用户是或不是存在
$t_struname = $_post[“f_uname”];
$t_strpwd = $_post[“f_pwd”];
$t_strsql = “select * from tbl_users where username=’$t_struname’
and password = ‘$t_strpwd’ limit 0,1”;

if ( $t_hres = mysql_query($t_strsql) )
{
// 成功查询现在的管理. 略…
}
}
?>

<html><head><title>sample
test</title></head>
<body>
<form method=post action=””>
username: <input type=”text” name=”f_uname”
size=30><br>
password: <input type=text name=”f_pwd” size=30><br>

<input type=”submit” name=”f_login” value=”登录”>
</form>
</body> 

当magic_quotes_gpc = on 时,它会将提交的变量中有着的
‘(单引号)、”(双号号)、(反斜线)、空白字符,都为在前方自动抬高 。上边是
php 的合法证实:

 

view sourceprint?

 

 

 

magic_quotes_gpc boolean

在那么些本子中,当用户输入不奇怪的用户名和密码,如果值分别为
zhang3、abc123,则交给的 sql 语句如下:
复制代码 代码如下:

 

select * from tbl_users
where username=’zhang3′ and password = ‘abc123’ limit 0,1

sets the magic_quotes state for gpc
(get/post/cookie)
operations. when magic_quotes are on, all ‘ (single-quote), ” (double
quote), (backslash) and nul’s are escaped with a backslash automatically

万一攻击者在 username 字段中输入:zhang3′ or 1=1 #,在 password 输入
abc123,则交由的 sql 语句产生如下:
复制代码 代码如下:

即使未有转义,即 off 情形下,就能够让攻击者有隙可乘。以下列测验脚本为例:

select * from tbl_users
where username=’zhang3′ or 1=1 #’ and password = ‘abc123’ limit 0,1

 1<?
 2if ( isset($_post[“f_login”] ) )
 3{
 4  //
连接数据库教程…
 5  // …代码略…
 6
 7  // 检查用户是或不是留存
 8  $t_struname = $_post[“f_uname”];
 9  $t_strpwd = $_post[“f_pwd”];
10  $t_strsql = “select * from tbl_users where
username=’$t_struname’ and password = ‘$t_strpwd’ limit 0,1”;
11
12  if ( $t_hres = mysql_query($t_strsql) )
13  {
14    // 成功查询之后的管理. 略…
15  }
16}
17?>
18
19<html><head><title>sample
test</title></head>
20<body>
21<form method=post action=””>
22  username: <input type=”text” name=”f_uname”
size=30><br>
23  password: <input type=text name=”f_pwd” size=30><br>
24
25  <input type=”submit” name=”f_login” value=”登录”>
26</form>
27</body>

由于 # 是 mysql中的注释符,
#后来的语句不被实行,达成上那行语句就成了:
复制代码 代码如下:

 

select * from tbl_users
where username=’zhang3′ or 1=1

在这些本子中,当用户输入不荒谬的用户名和密码,要是值分别为
zhang3、abc123,则交由的 sql 语句如下:

  那样攻击者就足以绕过证实了。纵然攻击者知道数据库结构,那么它构建一个union select,那就更惊恐了:

1 select * from tbl_users
2 where username=’zhang3′ and password = ‘abc123’ limit 0,1

  假设在 username 中输入:zhang3 ‘ or 1 =1 union select cola,
colb,cold from tbl_b #

 

  在password 输入: abc123,

一经攻击者在 username 字段中输入:zhang3′ or 1=1 #,在 password
输入 abc123,则交由的 sql 语句产生如下:

  则交由的 sql 语句形成:
复制代码 代码如下:
select * from tbl_users
where username=’zhang3 ‘

1 select * from tbl_users
2 where username=’zhang3′ or 1=1 #’ and password = ‘abc123’ limit 0,1

or 1 =1 union select cola, colb,cold from tbl_b #’ and password =
‘abc123’ limit 0,1

 

  那样就十分惊险了。借使agic_quotes_gpc选项为
on,引号被转义,则上边攻击者营造的抨击语句就能够化为那样,进而不可能直达其指标:
复制代码 代码如下:

 

select * from tbl_users
where username=’zhang3′ or 1=1 #’
and password = ‘abc123’
limit 0,1

select * from tbl_users
where username=’zhang3 ‘ or 1 =1 union select cola, colb,cold from
tbl_b #’
and password = ‘abc123’ limit 0,1

 

 

由于 # 是 mysql中的注释符, #尔后的语句不被实践,达成上那行语句就成了:

 

1 select * from tbl_users
2 where username=’zhang3′ or 1=1

二. magic_quotes_gpc = on 时的注入攻击
  当 magic_quotes_gpc = on 时,攻击者不可能对字符型的字段进行 sql
注入。那并不表示这就安然了。那时,能够透过数值型的字段举行sql注入。

 

 

 

  在新型版的 mysql 5.x
中,已经严俊了数据类型的输入,已暗许关闭自动类型转变。数值型的字段,不能够是引号标志的字符型。也正是说,假如uid 是数值型的,在原先的 mysql 版本中,那样的口舌是官方的:
复制代码 代码如下:

 

insert into tbl_user set uid=”1″;
select * from tbl_user where uid=”1″;

与此相类似攻击者就可以绕过证实了。倘若攻击者知道数据库结构,那么它营造三个union select,那就更危急了:

  在新式的 mysql 5.x 中,上面包车型大巴语句不是法定的,必须写成这么:
复制代码 代码如下:
insert into tbl_user set uid=1;
select * from tbl_user where uid=1;

假设在 username 中输入:zhang3 ‘ or 1 =1 union select cola, colb,cold
from tbl_b #

  那样本人认为是不错的。因为作为开垦者,向数据库提交准确的适合法则的数据类型,那是最宗旨的需要。

在password 输入: abc123,

  那么攻击者在 magic_quotes_gpc = on
时,他们怎么攻击呢?很轻便,便是对数值型的字段进行 sql 注入。以下列的
php 脚本为例:
复制代码 代码如下:

则交由的 sql 语句产生:

<?
if ( isset($_post[“f_login”] ) )
{
// 连接数据库…
// …代码略…

// 检查用户是还是不是留存
$t_struid = $_post[“f_uid”];
$t_strpwd = $_post[“f_pwd”];
$t_strsql = “select * from tbl_users where uid=$t_struid and
password = ‘$t_strpwd’ limit 0,1”;
if ( $t_hres = mysql_query($t_strsql) )
{
// 成功查询之后的管理. 略…
}

}
?>
<html><head><title>sample
test</title></head>
<body>
<form method=post action=””>
user id: <input type=”text” name=”f_uid” size=30><br>

password: <input type=text name=”f_pwd” size=30><br>
<input type=”submit” name=”f_login” value=”登录”>
</form>
</body>

1 select * from tbl_users
2 where username=’zhang3 ‘
3 or 1 =1 union select cola, colb,cold from tbl_b #’ and password =
‘abc123’ limit 0,1

 

 

 

 

  上边这段脚本要求用户输入 userid 和 password
登陆。贰个好端端的话语,用户输入 1001和abc123,提交的 sql 语句如下:

 

 

这么就一定危险了。倘使agic_quotes_gpc选项为
on,引号被转义,则上边攻击者营造的口诛笔伐语句就可以化为那样,进而不能够到达其指标:

select * from tbl_users where userid=1001 and password = ‘abc123’
limit 0,1
  倘若攻击者在 userid 处,输入:1001 or 1 =1 #,则注入的sql语句如下:

1 select * from tbl_users
2 where username=’zhang3′ or 1=1 #’
3 and password = ‘abc123’
4 limit 0,1
5
6 select * from tbl_users
7 where username=’zhang3 ‘ or 1 =1 union select cola, colb,cold from
tbl_b #’
8 and password = ‘abc123’ limit 0,1

select * from tbl_users where userid=1001 or 1 =1 # and password =
‘abc123’ limit 0,1
  攻击者达到了目标。

 

 三. 怎么样防止 php sql 注入攻击
  怎么样防守 php sql
注入攻击?笔者感到最关键的一些,就是要对数据类型进行反省和转义。计算的几点准则如下:

 

php.ini 中的 display_errors 选项,应该设为 display_errors = off。那样
php 脚本出错之后,不会在 web
页面输出错误,防止让攻击者分析出有作的音信。
调用 mysql_query 等 mysql 函数时,前边应该加上 @,即
@mysql_query(…),这样 mysql
错误不会被输出。同理以防让攻击者深入分析出有用的音信。其余,有个别技师在做开荒时,当
mysql_query出错时,习于旧贯输出错误以及 sql 语句,举例:
复制代码 代码如下:

 

$t_strsql = “select a from b….”;
if ( mysql_query($t_strsql) )
{
// 准确的拍卖
}
else
{
echo “错误! sql 语句:$t_strsql rn错误新闻”.mysql_query();
exit;
}

二. magic_quotes_gpc = on 时的注入攻击

  这种做法是一对一危急和鸠拙的。假设一定要那样做,最棒在网站的安排文件中,设三个全局变量或概念一个宏,设一下
debug 标志:

当 magic_quotes_gpc = on 时,攻击者不可能对字符型的字段进行 sql
注入。那并不表示那就高枕而卧了。那时,能够透过数值型的字段进行sql注入。

全局配置文件中:
复制代码 代码如下:

在风靡版的 mysql 5.x
中,已经严俊了数据类型的输入,已默许关闭自动类型调换。数值型的字段,不能够是引号标识的字符型。也正是说,假如uid 是数值型的,在在此在此以前的 mysql 版本中,那样的话语是合法的:

define(“debug_mode”,0); // 1: debug mode; 0: release mode

//调用脚本中:
$t_strsql = “select a from b….”;
if ( mysql_query($t_strsql) )
{
// 正确的管理
}
else
{
if (debug_mode)
echo “错误! sql 语句:$t_strsql rn错误新闻”.mysql_query();
exit;
}

1 insert into tbl_user set uid=”1″;
2 select * from tbl_user where uid=”1″;

对交付的 sql 语句,进行转义和种类检查。
 四. 小编写的一个武威参数获取函数
  为了以免万一用户的荒谬数据和 php + mysql 注入 ,我写了三个函数
papi_getsafeparam(),用来得到安全的参数值:
复制代码 代码如下:

 

define(“xh_param_int”,0);
define(“xh_param_txt”,1);
function papi_getsafeparam($pi_strname, $pi_def = “”, $pi_itype =
xh_param_txt)
{
if ( isset($_get[$pi_strname]) )
$t_val = trim($_get[$pi_strname]);
else if ( isset($_post[$pi_strname]))
$t_val = trim($_post[$pi_strname]);
else
return $pi_def;

// int
if ( xh_param_int == $pi_itype)
{
if (is_numeric($t_val))
return $t_val;
else
return $pi_def;
}

// string
$t_val = str_replace(“&”, “&”,$t_val);
$t_val = str_replace(“<“, “<“,$t_val);
$t_val = str_replace(“>”, “>”,$t_val);
if ( get_magic_quotes_gpc() )
{
$t_val = str_replace(“””, “””,$t_val);
$t_val = str_replace(“””, “‘”,$t_val);
}
else
{
$t_val = str_replace(“””, “””,$t_val);
$t_val = str_replace(“‘”, “‘”,$t_val);
}
return $t_val;
}

  

 

 

 

 

在新式的 mysql 5.x 中,上边的语句不是官方的,必须写成这么:

在这些函数中,有四个参数:

1 insert into tbl_user set uid=1;
2 select * from tbl_user where uid=1;

 

 

$pi_strname: 变量名
$pi_def: 默认值
$pi_itype: 数据类型。取值为 xh_param_int, xh_param_txt,
分别代表数值型和文本型。
  要是供给是数值型,那么调用 is_numeric()
判定是或不是为数值。如若不是,则赶回程序内定的私下认可值。

 

  轻便起见,对于文本串,小编将用户输入的全体惊险字符(包蕴html代码),全体转义。由于
php 函数 addslashes()存在漏洞,小编用
str_replace()直接沟通。get_magic_quotes_gpc() 函数是 php
的函数,用来推断 magic_quotes_gpc 选项是还是不是展开。

网站地图xml地图