You are here

25 SQL注入攻击

admin 的头像
Submitted by admin on 星期五, 2015-09-18 09:46

作者:老葛,北京亚艾元软件有限责任公司,http://www.yaiyuan.com

 SQL注入攻击是黑客对数据库进行攻击的常用手段之一。随着B/S模式应用开发的发展,使用这种模式编写应用程序的程序员也越来越多。黑客通过把SQL命令插入到Web表单提交的查询字符串,最终达到欺骗服务器并执行恶意的SQL命令

/**

 * Implements hook_menu().

 */

function sql_injection_menu() {

  $items = array();

$items['sql/injection'] = array(

    'title' => 'SQL注入实例',

    'description' => 'SQL注入实例.',

    'page callback' => 'sql_injection_page_callback',

    'access callback' => TRUE,

  );

return $items;

}

 

/**

 * 页面回调函数.

 */

  $result = db_query("SELECT n.nid, n.title FROM

function sql_injection_page_callback(){

  //假定这个type是用户通过表单输入的,为了方便,这里直接赋值了。

  $type = 'page';

//$output ="123";

 {node} n WHERE n.type = '$type'");

  $items = array();

foreach($result as $record){   

  $items[] = l($record->title, "node/{$record->nid}");

}

return theme('item_list', array('items' => $items));

}

访问http://localhost/thinkindrupal/sql/injection,一切正常。我们得到想要的基本页面列表,如图所示。

图片1.png 

图 简单的page页面标题列表

 

 

 

    尽管这段程序也能正常工作,但是却存在安全隐患。将变量$type直接放到SQL中,这样用户就有可能发动SQL注入攻击。让我们将$type设置为:

$type = "page' UNION SELECT s.sid, s.sid FROM {sessions} s WHERE s.uid = 1 #";

    假定这就是用户的输入,此时我们将得到:

 

图片2.png 

图 在db_query()中不使用占位符引起的SQL注入

 

    看到什么了?像密码一样的信息,是的,我们把用户1的会话信息也显示了出来。出问题了把。当然,这危害还比较小,黑客有可能会使用SQL注入,获取更多的信息。比如注册用户的各种个人信息。

 

我们来对这段代码进行改进,其实使用Drupal7中的占位符,就可以避免SQL注入。代码如下:

$result = db_query("SELECT n.nid, n.title FROM {node} n WHERE n.type = :type",array(':type' => $type));

如果用户输入的是:

$type = "page' UNION SELECT s.sid, s.sid FROM {sessions} s WHERE s.uid = 1 #";

此时结果为空。我们已经有效的防止了SQL注入攻击。

我们也可以采用动态查询的形式,代码如下所示:

$result = db_select('node', 'n')

          ->fields('n',array('nid','title'))

            ->condition('n.type',$type)  

            ->execute();

这也同样可以避免SQL注入攻击。


Drupal版本: