php基础知识(2)-sql注入

php基础知识-sql注入

示例代码下载页 http://xieye.iteye.com/blog/1336095(在附件)

sql注入是指:黑客利用编写不严谨的php程序中的漏洞,进行数据窃取或数据破坏的行为。

如果没有test库,首先建立test数据库。

然后,建一个用户表
use test;


-- 创建用户表
CREATE TABLE member (
  id int(11) NOT NULL AUTO_INCREMENT COMMENT '主键ID',
  username varchar(255) NOT NULL DEFAULT '' COMMENT '用户名',
  password varchar(255) NOT NULL DEFAULT '' COMMENT '密码',
  primary KEY (id )
)default charset=utf8 COMMENT='会员表';

-- 往会员表插入两条数据。
insert into member(username,password)values('name1', 'name1');
insert into member(username,password)values('name2', 'name2');

-- 检查表
show tables;

可以写个简单的程序来测试数据库的正确性。

代码说明:
文件夹是sql_injection
3.php是列出所有用户,同时也是一个公共文件,被别的文件调用。
4.php是测试sql注入,程序编写错误的例子
5.php是测试sql注入,程序防止注入、编写正确的例子。

演示:
首先列出所有用户的程序:
http://localhost/command/peixun/sql_injection/3.php

一个错误的导致sql注入的程序(首先确保magic_quotes_gpc = 0)
http://localhost/command/peixun/sql_injection/4.php
首先在用户名输入admin,密码输入1,发现是正确的。
再次注册,在用户名输入
5', 'f'); delete from member; -- \
密码输入1

点击注册。
发现提示一堆致命错误,这时开新窗口,重新输入
http://localhost/command/peixun/sql_injection/3.php

发现刚才注册的用户数据没有了,说明被注入了delete语句。

光防止delete是不够的,重要的是确保每个字符串里面都被转义过,很多php框架都实现了此功能,当然必须要调用才可以。

一个正确的的防止sql注入的程序
http://localhost/command/peixun/sql_injection/5.php

看代码可知,代码使用了zend的防止注入的功能,不会遭受注入了,在zend框架中,更多防注入使用的是?参数,请自行阅读zend文档。

另外,其实把php.ini中的magic_quotes_gpc打开也可以防注入,但是付作用太多,所以一般不用。

代码可下载。
3.php
<?php
//测试sql注入的公共文件
require_once('../Public/CommandLine.php');

$db = Sys::getdb();

$sql ="select * from test.member";
$result = $db->fetchAll($sql);

$html ="
<h2>当前所有用户的列表</h2>
<ul>";
foreach ($result as $value) {
    $html .= "<li>{$value['username']}</li>";
    
}
$html .= '</ul>';

$html .= "<br /><a href=\"4.php\">注册用户</a>";

echo $html;



4.php
<?php
//测试sql注入:错误的例子
require_once('../Public/CommandLine.php');


$isget = ($_SERVER['REQUEST_METHOD'] == 'GET') ? 1 : 0;
if ($isget) {
    $html = <<<longs
<html>    
<body>
  <h3>注册用户页面</h3>
  <form method="post">
    请输入用户名:<input type="text" name="username" value=''>
    请输入密码:  <input type="text" name="password" value=''>
    <input type="submit" value="注册">
  </form>
  
  
</body>  
</html>  
longs;
    echo $html;
    
} else {
    //危险的例子,会导致sql注入
    $db = Sys::getdb();
    
    $sql = "insert into member(username, password)values('" . $_POST['username'] . 
           "', '" . md5($_POST['password']) . "')";
   echo $sql;
    $db->query($sql);
}

//无论如何,最后显示所有的用户
include('3.php');


5.php
<?php
//测试sql注入,正确的例子
require_once('../Public/CommandLine.php');


$isget = ($_SERVER['REQUEST_METHOD'] == 'GET') ? 1 : 0;
if ($isget) {
    $html = <<<longs
<html>    
<body>
  <h3>注册用户页面(修改版)</h3>
  <form method="post">
    请输入用户名:<input type="text" name="username" value=''>
    请输入密码:  <input type="text" name="password" value=''>
    <input type="submit" value="注册">
  </form>
  
  
</body>  
</html>  
longs;
    echo $html;
    
} else {
    //正确的例子, 不会导致sql注入
    $db = Sys::getdb();
    $sql = "insert into test.member(username, password)values('" . $_POST['username'] . 
           "', '" . md5($_POST['password']) . "')";
  
    $db->insert("test.member", array(
        'username'=> $_POST['username'] ,
        'password' => $_POST['password'],
    ));
    
    
//    echo $_POST['name1'];
    
}

//无论如何,最后显示所有的用户
include('3.php');



你可能感兴趣的:(sql注入)