PHP MySQLI 防止 SQL 注入

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/16282103/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-25 10:50:27  来源:igfitidea点击:

PHP MySQLI Prevent SQL Injection

phpmysqlsecuritymysqlicode-injection

提问by user2201765

I've build a website that will be going live soon and just have a couple questions about preventing SQL injection, I understand how to use mysqli_real_escape_stringbut I'm just wondering if I have to use that on all variables that I'm getting for my SQL statement and do I have to use it when I'm doing select statements also or just on insert update and delete? Also what other security would you recommend me implementing before I put the site live, thanks in advance for any help!

我已经建立了一个即将上线的网站,只是有几个关于防止 SQL 注入的问题,我知道如何使用,mysqli_real_escape_string但我只是想知道是否必须在我为我的所有变量中使用它SQL 语句,我是否也必须在执行 select 语句或仅在插入更新和删除时使用它?在我将网站上线之前,您还建议我实施哪些其他安全措施,在此先感谢您的帮助!

回答by Explosion Pills

Any query can be injected whether it's read or write, persistent or transient. Injections can be performed by ending one query and running a separate one (possible with mysqli), which renders the intended query irrelevant.

任何查询都可以被注入,无论是读还是写,是持久的还是瞬态的。可以通过结束一个查询并运行一个单独的查询(可能使用mysqli)来执行注入,这使得预期的查询无关紧要。

Any input to a query from an external source whether it is from users or even internal should be considered an argument to the query, and a parameter in the context of the query. Any parameter in a query needs to be parameterized. This leads to a properly parameterized query that you can create a prepared statement from and execute with arguments. For example:

任何来自外部源的查询输入,无论是来自用户还是内部,都应被视为查询的参数,以及查询上下文中的参数。查询中的任何参数都需要参数化。这会导致正确参数化的查询,您可以从中创建准备好的语句并使用参数执行。例如:

SELECT col1 FROM t1 WHERE col2 = ?

?is a placeholder for a parameter. Using mysqli, you can create a prepared statement using prepare, bind a variable (argument) to a parameter using bind_param, and run the query with execute. You don't have to sanitize the argument at all (in fact it's detrimental to do so). mysqlidoes that for you. The full process would be:

?是参数的占位符。使用mysqli,您可以使用来创建准备好的语句,使用prepare将变量(参数)绑定到参数bind_param,并使用运行查询execute。您根本不必清理论点(实际上这样做是有害的)。 mysqli为你做那个。完整的流程是:

$stmt = $mysqli->prepare("SELECT col1 FROM t1 WHERE col2 = ?");
$stmt->bind_param("s", $col2_arg);
$stmt->execute();

There is also an important distinction between parameterized queryand prepared statement. This statement, while prepared, is not parameterized and is thus vulnerable to injection:

参数化查询准备好的语句之间还有一个重要的区别。这个语句在准备好的时候没有参数化,因此容易受到注入:

$stmt = $mysqli->prepare("INSERT INTO t1 VALUES ($_POST[user_input])");

To summarize:

总结一下:

  • AllQueries should be properly parameterized (unless they have no parameters)
  • Allarguments to a query should be treated as hostile as possible no matter their source
  • 所有查询都应正确参数化(除非它们没有参数)
  • 无论来源如何,查询的所有参数都应尽可能视为敌对