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
PHP MySQLI Prevent SQL 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_string
but 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). mysqli
does 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
- 所有查询都应正确参数化(除非它们没有参数)
- 无论来源如何,查询的所有参数都应尽可能视为敌对