PHP代码易受SQL注入:如何使用' mysql_real_escape_string() '


PHP code vulnerable to SQL injection: how to work with `mysql_real_escape_string()`?

由于我从几年前的教程中学习,我最终得到了以下易受SQL注入攻击的代码。

谁能给我解释一下如何使用mysql_real_escape_string() ?这是目前的防弹方法吗?

//Function to sanitize values received from the form. Prevents SQL injection
    function clean($str) {
    $str = @trim($str);
    if(get_magic_quotes_gpc()) {
        $str = stripslashes($str);
    }
    return mysql_real_escape_string($str);
}
//Sanitize the POST values
$usr = $_SESSION['usr'];
$live = (isset($_POST['live']))?1:0;
$created = date("F j, Y, g:i a",time()+60*60);
$title= clean($_POST['title']);
$content = clean($_POST['content']);
//Create INSERT query
$qry = "INSERT INTO news( usr, live, created, title, content) VALUES( '$usr', '$live', '$created', '$title', '$content') ";
$result = @mysql_query($qry);

是的,这个很好。您可以使用预处理语句,但是

不要用@来隐藏所有的错误!

添加到查询字符串的所有内容都应该使用mysql_real_escape_string转义。它将阻止大多数SQL注入。但最好使用预处理语句

例子:

$pdo = new PDO($dsn,$username,$pass);
$stmt = $pdo->prepare("select * from Table where id=?");
if ($stmt->execute(array(1))){
    $content = $stmt->fetchAll();
}

参考PDO::__construct

是的。

注意,没有什么像"普遍消毒"这样的东西。我们就叫它引号,因为这就是它的意义所在。

在引用时,总是引用某些特定输出的文本,例如:

    mysql查询的字符串值mysql查询的like表达式
  1. json mysql正则表达式
  2. php正则表达式

对于每种情况,需要不同的引用,因为每种用法出现在不同的语法上下文中。这也意味着不应该在PHP的输入处引用,而应该在特定的输出处引用!这就是为什么像magic_quotes_gpc这样的功能被破坏的原因(我建议保持关闭)。

那么,在这些特殊情况下应该使用什么方法来引用呢?(请随意纠正我,可能有更现代的方法,但这些对我来说是有效的)

  1. mysql_real_escape_string($str)
  2. mysql_real_escape_string(addcslashes($str, "%_"))
  3. htmlspecialchars($str)
  4. json_encode() -仅用于utf8!我使用我的功能为iso-8859-2
  5. mysql_real_escape_string(addcslashes($str, '^.[]$()|*+?{}')) -在这种情况下不能使用preg_quote,因为反斜杠会被转义两次!
  6. preg_quote()

黑客攻击是无懈可击的;话虽如此,是的……mysql_real_escape_string()防止SQL注入攻击

我认为你的方法是sql注入保存

您可以使用mysql_real_escape_string来转义危险字符…

$sanitized_query = sprintf("SELECT * FROM table WHERE field='%s', mysql_real_escape_string($value));

我会这样做

sprintf(" SELECT * from table_name WHERE value = '%s'", mysql_escape_string("$var_value"));

sprintf()函数中的%s表示该参数被视为字符串并作为字符串呈现。

如果攻击发生了,就像前面的例子一样,发送的查询将是:查看源代码打印吗?

SELECT * FROM `members` WHERE username='john' AND password=''' OR ''''='''

,将返回一个空结果集。(源)