简体   繁体   English

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

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

As I was learning from couple of years old tutorials I have end up with following code which IS vulnerable for SQL injections.当我从几年前的教程中学习时,我最终得到了以下代码,这些代码易受 SQL 注入的影响。

Can someone explain to me how to work with mysql_real_escape_string() ?有人可以向我解释如何使用mysql_real_escape_string()吗? Is this currently bulletproof method?这是目前防弹的方法吗?

//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);

Yes, this one is fine.是的,这个很好。 You can use prepared statements , though不过,您可以使用准备好的语句

Do not use @ to hide all errors!不要使用@来隐藏所有错误!

Everything you append to query string you should escape with mysql_real_escape_string .您 append 查询字符串的所有内容都应该使用mysql_real_escape_string进行转义。 It will prevent most of SQL injections.它将阻止大多数 SQL 注射。 But better use prepared statements但最好使用准备好的语句

Example:例子:

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

See PDO::__construct for reference请参阅PDO::__construct以供参考

Nothing is bulletproof when it comes to hacking;黑客攻击没有什么是万无一失的。 having said that, yes.. mysql_real_escape_string() prevents SQL injection attacks.话虽如此,是的.. mysql_real_escape_string() 可以防止 SQL 注入攻击。

I think your method is sql injection save.我认为你的方法是 sql 注入保存。

I would do something like我会做类似的事情

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

The %s from the sprintf() function indicates that the argument is treated as and presented as a string. sprintf() function 中的 %s 表示该参数被视为字符串并显示为字符串。

If an attack is made such as the one from the previous example the query sent will be: view source print?如果进行攻击,例如上一个示例中的攻击,发送的查询将是:查看源打印?

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

and will return an empty result set.并将返回一个空的结果集。 (source) (资源)

Yes, it is.是的。 In this case.在这种情况下。

Note there is nothing like "universal sanitization".请注意,没有什么比得上“通用消毒”。 Let's call it just quoting , because that's what its all about.让我们称之为引用,因为这就是它的全部内容。

When quoting, you always quote text for some particular output , like:引用时,您总是引用某些特定 output的文本,例如:

  1. string value for mysql query mysql 查询的字符串值
  2. like expression for mysql query mysql 查询的like表达式
  3. html code html代码
  4. json json
  5. mysql regular expression mysql 正则表达式
  6. php regular expression php 正则表达式

For each case, you need different quoting, because each usage is present within different syntax context.对于每种情况,您需要不同的引用,因为每种用法都存在于不同的语法上下文中。 This also implies that the quoting shouldn't be made at the input into PHP, but at the particular output !这也意味着不应在 PHP 的输入处进行引用,而应在特定的 output 处进行引用 Which is the reason why features like magic_quotes_gpc are broken (I recommend to keep it switched off).这就是诸如magic_quotes_gpc之类的功能被破坏的原因(我建议将其关闭)。

So, what methods would one use for quoting in these particular cases?那么,在这些特定情况下引用什么方法? (Feel free to correct me, there might be more modern methods, but these are working for me) (请随时纠正我,可能有更现代的方法,但这些对我有用)

  1. mysql_real_escape_string($str)
  2. mysql_real_escape_string(addcslashes($str, "%_"))
  3. htmlspecialchars($str)
  4. json_encode() - only for utf8! json_encode() - 仅适用于 utf8! I use my function for iso-8859-2我将我的 function 用于 iso-8859-2
  5. mysql_real_escape_string(addcslashes($str, '^.[]$()|*+?{}')) - you cannot use preg_quote in this case because backslash would be escaped two times! mysql_real_escape_string(addcslashes($str, '^.[]$()|*+?{}')) - 在这种情况下你不能使用 preg_quote 因为反斜杠会被转义两次!
  6. preg_quote()

you can use mysql_real_escape_string, to escape dangerous characters...您可以使用 mysql_real_escape_string 来转义危险字符...

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM