2013-03-13 54 views
2
function Query() 
{ 
    $args = func_get_args(); 

    if (sizeof ($args) > 0) 
    { 
     $query = $args[0]; 

     for ($i = 1; $i < sizeof ($args); $i++) 
       $query = preg_replace ("/\?/", "'" . mysql_real_escape_string ($args[$i]) . "'", $query, 1); 
    } 
    else 
    { 
      return FALSE; 
    } 

我有这样的功能。基本上,我做出这样的查询:mysql(i)_real_escape_string,安全依赖?

$this->Query('SELECT * FROM USERS WHERE Username = ? AND Points < ?', $username, $points); 

它目前支持弃用mysql功能,但适应mysqli会在我的类mysqli更换mysql一样简单。

这是一个安全的方法来依靠对SQL注入攻击?每个问号都被mysql_real_escape_string自动消毒,我从来没有遇到过问题,但是我应该使用mysqli_real_escape_string进行消毒?

我知道的mysqli的预处理语句,但使用bindParam每个变量似乎有点矫枉过正了我。

您认为如何?

+4

*“似乎有点矫枉过正”?* *“矫枉过正”有一个简单,可靠,难以搞砸的机制来确保查询语法的有效性并防止SQL注入? – deceze 2013-03-13 15:55:43

+0

*“,但对每个变量使用'bindParam'似乎对我有点矫枉过正”*什么?真的吗?这从来没有矫枉过正。 – 2013-03-13 15:55:48

+1

不能依赖mysql_real_escape_string(可以在不依赖嵌入字符串的情况下执行“小型桌面表”);准备好的语句可能看起来过分了......直到数据库被入侵的地步 – 2013-03-13 15:55:54

回答

1

一个真正伟大的一天 - 第二好的尝试建立一排一个合理的数据库抽象层。

我应该使用mysqli_real_escape_string进行消毒吗?

没有。
只因为此功能不消毒任何东西。

转换为格式 SQL字符串文字这个函数是必须的,无法避免或替换。
所以,你正在正确使用这个功能,格式化字符串只有并格式化它们无条件
所以,你有你的疑问完全安全,只要你可以使用?标记来替换实际数据(并且 - 甚至可以让挑剔的投诉空闲 - 只要您使用mysql(i)_set_charset()函数设置SQL编码)。

如果有人致电您的方法 - 只是要求他们证明代码的完整片段显示一定的脆弱性。

但是,请让我将您的注意力放在一些重要的事情上。

  1. 动态SQL查询零件仅限于字符串。例如,这两个查询将不会与您的功能一起使用:

    SELECT * FROM table LIMIT ?,? 
    SELECT * FROM table ORDER BY ? 
    

    只是因为数字和标识符要求不同的格式。
    所以,最好使用类型暗示占位符,告诉你的功能,适用

  2. 要运行一个查询只是工作的一部分的格式。你也需要得到结果。为什么不让他们已经,而不用不必要的电话膨胀你的代码?
  3. 应该有一种方法来插入文字?标记为查询而不解析它们。

请看看my class,它建立在与您的原理完全相同的原则上,但是我在上面提到了一些改进。我希望你会发现它有用或至少值得借鉴一两个想法。

+0

好的。我阅读你的回复,但无法理解一些部分,所以如果你能再次回复,我会很感激。一个。 mysqli_real_escape_string()不会净化任何东西。为什么?它不能保证我传递的参数是什么? 1.使用LIMITS进行查询是可行的,因为我可以发送两个整数参数。 (我相信我经常在我的函数中使用限制。)2.我使用mysql_row_assoc得到结果,但是我将它们从这个函数中删除,因为它们是无关的。 3。你的意思是我应该找到一种方法来跳过参数中的合法问号? – 2013-03-13 21:26:18

+0

由于某种原因,我昨天错过了你的评论,但在这里你走了。一个。 http://stackoverflow.com/a/9296858/ 1.用现在的代码它没有。也许你有另一种情况 - 那么是的。 2.很好,但我希望你不要自动化返回的类型3.不是在参数中,而是在查询中。这不是什么大问题。如果你发布整个代码,我会非常感激 - 所以,我不需要任何假设。 – 2013-03-14 10:40:20

+0

所以,一个。我的方法是安全的,没有注射问题? 1.你的意思是什么?整数,?字符串,?标识符而不是?所以他们都得到不同的处理? 3.如果有办法与你联系,我可以寄给你我写的全班。您不仅可以看到整个功能,但是如果专家会评论我的课程,我会很感激。 PS。顺便说一句,谢谢你。你已经像我所有的stackoverflow问题一样回答了很多答案。对此,我真的非常感激。 – 2013-03-14 11:59:06

2

使用绑定的参数是矫枉过正,并应符合规定。它会更有效地逃脱并准备好你的参数。

$stmt = mysqli_prepare($link, "INSERT INTO CountryLanguage VALUES (?, ?, ?, ?)"); 
mysqli_stmt_bind_param($stmt, 'sssd', $code, $language, $official, $percent); 

$code = 'DEU'; 
$language = 'Bavarian'; 
$official = "F"; 
$percent = 11.2; 

/* execute prepared statement */ 
mysqli_stmt_execute($stmt); 

这是否真的看起来矫枉过正?

Documentation

+0

当然可以。它需要7行代码,而OP需要** 1 **。对十几个领域来说,它将是二十个,但对于OP来说仍然是一个。 – 2013-03-13 19:36:48

0

,如果你现在使用的mysqli为mysql。最好使用mysqli_real_escape_string。 请注意参数顺序已被修改。 (%和_仍然没有逃脱)今天