简体   繁体   English

sprintf() 如何防止 SQL 注入?

[英]How does sprintf() protect against SQL injection?

I have heard that sprintf() protects against SQL injection.我听说sprintf()可以防止 SQL 注入。 Is it true?这是真的吗? If so, how?如果是这样,怎么做?

Why people are recommending to write query like this:为什么人们推荐这样写查询:

$sql = sprintf('SELECT * FROM TABLE WHERE COL1 = %s AND COL2 = %s',$col1,$col2);

sprintf won't protect you! sprintf 不会保护你! It only replaces the %s它只替换%s

you must mysql_real_escape_string so:你必须 mysql_real_escape_string 所以:

$sql = sprintf('SELECT * FROM TABLE WHERE COL1 = "%s" AND COL2 = "%s"',
mysql_real_escape_string($col1),
mysql_real_escape_string($col2));

is safer injection注射更安全

note: I suggest you take a look at PDO , it is what I like to use for DBconections and queries注意:我建议你看看PDO ,这是我喜欢用于 DBconections 和查询

That doesn't do any protection.那没有任何保护作用。 Using sprintf makes for more readable code then dropping in and out of a string to run mysql_real_escape_string over each of the variables … but that example doesn't escape the variables at the end so that advantage is lost.使用sprintf可以使代码更具可读性,然后放入和取出一个字符串以在每个变量上运行mysql_real_escape_string ……但是该示例最后并没有转义变量,因此失去了优势。

If you want decent protection, use something that provides bound parameters .如果您想要体面的保护,请使用提供绑定参数的东西。

Using sprintf might protect against SQL injection for numeric fields:使用 sprintf 可以防止数字字段的 SQL 注入:

$sql = sprintf("SELECT * FROM table WHERE col1 = %i", $col1);

By using sprintf in this way, you can be sure that $col1 will be converted to an integer--although it might generate an error or warning, if it's not truly an integer.通过以这种方式使用 sprintf,您可以确保 $col1 将被转换为整数——尽管它可能会生成错误或警告,如果它不是真正的 integer。

The proper way to protect against SQL injection is to check all of your input values, and do escaping.防止 SQL 注入的正确方法是检查所有输入值,然后执行 escaping。 But that's much more thoroughly covered in other questions, so I'm not going to go into detail here.但这在其他问题中涵盖得更彻底,所以我不会在这里详细介绍 go。

It obviously doesn't and if you've actually read that in a book or tutorial you should automatically discard it for future reference.它显然没有,如果你真的在书或教程中读过它,你应该自动丢弃它以供将来参考。

However, it can be a practical way to generate output that needs further processing.但是,生成需要进一步处理的 output 可能是一种实用的方法。 Please compare:请比较:

echo '<p>Hello, <strong></strong>' . htmlspecialchars($name) . ', welcome to ' . htmlspecialchars($place). '</p>';

echo sprintf('<p>Hello, <strong>%s</strong>, welcome to %s</p>',
    htmlspecialchars($name),
    htmlspecialchars($place)
);

Same applies to other kind of output, such as SQL code, but of course you still need to do something to input in order to make it safe: sprintf() is just a regular string function that's unaware of SQL and databases. Same applies to other kind of output, such as SQL code, but of course you still need to do something to input in order to make it safe: sprintf() is just a regular string function that's unaware of SQL and databases.

Please note that bind parameters use a similar syntax:请注意,绑定参数使用类似的语法:

// Fictional DB abstraction layer
$sql = 'SELECT foo_id
    FROM foo
    WHERE name=:name AND status=:status';
$params = array(
    'name' => $name,
    'status' => $status,
);
$result = $db->run($sql, $params);

That's why I particularly find easier to use those DB libraries that provide this syntax, such as PDO.这就是为什么我特别发现使用那些提供这种语法的数据库库更容易,例如 PDO。

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

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