2015-08-21 78 views
1

我有我的控制器上运行此代码:笨SQL注入

$sql = "SELECT * FROM user WHERE id = " . $this->input->get('foo'); 
$foo = $this->db->query($sql); 
echo '<pre>'; 
print_r($foo->result()); 
echo '</pre>'; 
die(); 

我发现,如果我用这个网址:
www.site.com?foo=1 OR 1 = 1
所有用户表的数据如下所示:

Array 
(
[0] => stdClass Object 
    (
     [id] => 1 
     [email] => [email protected] 
     [password] => aaa 
    ) 
[1] => stdClass Object 
    (
     [id] => 1 
     [email] => [email protected] 
     [password] => bbb 
    ) 
[2] => stdClass Object 
    (
     [id] => 1 
     [email] => [email protected] 
     [password] => ccc 
    ) 
) 

是否有可能运行另一个查询从user_phone表中返回数据?

表:

CREATE TABLE `user` (
    `id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT, 
    `email` VARCHAR(100) NOT NULL, 
    `password` VARCHAR(255) NOT NULL 
    PRIMARY KEY (`id`), 
) ENGINE=INNODB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 


CREATE TABLE `user_phone` (
    `id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT, 
    `id_user` INT(11) UNSIGNED NOT NULL, 
    `number` INT(11) UNSIGNED NOT NULL 
    PRIMARY KEY (`id`) 
) ENGINE=INNODB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 

数据:

INSERT INTO `user`(`email`,`password`) VALUES ('[email protected]','aaa'); 
INSERT INTO `user`(`email`,`password`) VALUES ('[email protected]','bbb'); 
INSERT INTO `user`(`email`,`password`) VALUES ('[email protected]','ccc'); 

INSERT INTO `user_phone`(`id_user`,`number`) VALUES ('1','911911911'); 
INSERT INTO `user_phone`(`id_user`,`number`) VALUES ('1','922922922'); 
INSERT INTO `user_phone`(`id_user`,`number`) VALUES ('2','955955955'); 
INSERT INTO `user_phone`(`id_user`,`number`) VALUES ('3','711711711'); 

THKS

编辑:
我知道的现有机制,以防止这种HAPP的效果图创作。
我的问题是如果可能,以及如何,我可以从其他表中获取数据。

+1

使用'real_escape_string'或类似的东西,以防止注射。永远不要相信用户输入 – SuperDJ

+3

你可以使用参数绑定,而不是直接连接类似的值吗?你本质上*作为代码执行用户输入*。 – David

+1

你是要求注射字符串吗?简而言之,是的,可以运行一个查询来输出当前mysql用户可以访问的任何和所有表/数据库的数据,以及更多 –

回答

3

我认为这将是这样的。

www.site.com?foo=1 OR 1 = 1 union select * from user_phone where user_phone.id_user = user.id 
+1

嗨volkinc!它失败了user.id('where子句'中的未知列'user.id'),但我得到的图片。很多! – random425

0

因为这个原因,CI带有函数来逃避变量。

$foo = $this->input->get('foo'); 
$foo = $this->db->escape($foo); 
$sql = "SELECT * FROM user WHERE id = {$foo}"; 
$foo = $this->db->query($sql); 
echo '<pre>'; 
print_r($foo->result()); 
echo '</pre>'; 
die(); 
+1

嗨,吉姆。我知道逃生方法。我的问题是这个代码是否可能从其他表中返回数据。 – random425

0

您应该能够使用这样的查询绑定:

$sql = "SELECT * FROM user WHERE id = ? AND name = ?"; 
$foo = $this->db->query($sql, array('foo', 'bar')); 

至于从其它表中获取数据,你只需要构造一个更复杂的SQL查询

0

您询问了从2个表中查询数据,查询2个可以使用join的相关表。在你的例子中user和user_phone是相关的。你使用下面的演示来执行sql查询。用户primary_key是user_phone表中的胶水。 1 - 选择* 2 - 传递我们想要检索 3的ID - 从表 4 - 执行连接或多个连接 5 - 得到的结果 试试这个

$this -> db -> select('*'); 
$this -> db -> where('id' => '1'); 
$this -> db -> from('user'); 
$this -> db -> join('user_phone', 'user_phone.id_user = user.id'); 
$query = $this -> db -> get(); 
+1

你能解释你的答案吗?如果一个答案解释了正在做什么以便其技术可以应用于其他情况,那么答案就会更有用。 –

+2

对,我有点急,我添加了一些信息来解释这个陈述是什么以及它是如何完成的。感谢您指出,虽然:)。 – mdamia

+1

嗨mdamia。请你回复。基本上,我的问题是如何使用** SQL注入**连接表,而不是使用代码。 – random425