我正在使用mysql,并试图阻止那些试图使用我的单个查询来运行多个查询的人的不必要的查询注入。例如,当我有参数“?id=3”时,人们可以尝试使用=“id=3;drop table users”运行它现在,我知道避免这种情况的最佳方法是解析和检查参数,但有没有办法将连接查询分隔符从“;”更改为“;”类似于“%^#$%@#$^$”?
csbfibhn1#
默默无闻的安全是无用的。花点时间编写适当的代码以防止SQL注入攻击。提前完成这项工作将比在成功运行了针对代码的攻击之后完成这项任务花费更少的成本!
kgsdhlau2#
防御注入攻击的最佳方法是使用Prepared Statements。通过使用Prepared Statements,您可以对大多数注入攻击免疫(当然,这不是您需要考虑的唯一安全漏洞,但它们是一个非常重要的漏洞)
gudnpqoy3#
语句DELIMITER配置是仅在mysql客户端工具中的内置命令。您不能更改multi-statements的分隔符。它总是分号。此外,默认情况下,MySQL API一次只允许执行一条语句。除非您明确表示enable multi-statements,否则您正在讨论的示例无法工作。此外,多语句并不是SQL注入的唯一矢量。即使您可以更改语句分隔符,它也无法防止修改单个给定语句的SQL注入。
DELIMITER
UPDATE Accounts SET PASSWORD = '...' WHERE account_id = $id
在本例中,如果$id的值为“1234 OR 1=1”,则攻击者已更改了所有帐户的密码,可能包括特权用户。但没有涉及多个声明。在编写代码时,仍然需要注意安全问题。没有银弹可以防止SQL注入。即使是查询参数也不是SQL注入的万能药。参数仅取代SQL表达式中的值。在许多常见情况下,仍然需要将应用程序变量插入到SQL字符串中。例如,参数化IN() predicate 时,或选择ORDER BY表达式时。不要听那些说准备好的查询可以100%防止安全漏洞的人的话。另请参阅我的演示文稿SQL Injection Myths and Fallacies,或我的书SQL Antipatterns Volume 1: Avoiding the Pitfalls of Database Programming中关于SQL注入的章节。
$id
1234 OR 1=1
IN()
ORDER BY
3mpgtkmj4#
当您调用mysql_query或mysql_real_query时,它无论如何都不会运行多个语句,因此语句分隔符并不重要。您可以使用enable multiple statements per query when you connect,但由于您试图避免该功能,请不要启用它。避免SQL注入的一个更好的选择是use prepared statements。从mysql_stmt_init和mysql_stmt_prepare开始,用占位符表示语句的参数,然后在mysql_stmt_execute之前用mysql_stmt_bind_param填充参数。如果您不是直接调用API,那么您拥有的任何 Package 库都应该为准备好的语句提供支持。(如果它不支持它们,那么考虑切换到更好的 Package 器。)
mysql_query
mysql_real_query
mysql_stmt_init
mysql_stmt_prepare
mysql_stmt_execute
mysql_stmt_bind_param
4条答案
按热度按时间csbfibhn1#
默默无闻的安全是无用的。花点时间编写适当的代码以防止SQL注入攻击。提前完成这项工作将比在成功运行了针对代码的攻击之后完成这项任务花费更少的成本!
kgsdhlau2#
防御注入攻击的最佳方法是使用Prepared Statements。
通过使用Prepared Statements,您可以对大多数注入攻击免疫(当然,这不是您需要考虑的唯一安全漏洞,但它们是一个非常重要的漏洞)
gudnpqoy3#
语句
DELIMITER
配置是仅在mysql客户端工具中的内置命令。您不能更改multi-statements的分隔符。它总是分号。此外,默认情况下,MySQL API一次只允许执行一条语句。除非您明确表示enable multi-statements,否则您正在讨论的示例无法工作。
此外,多语句并不是SQL注入的唯一矢量。即使您可以更改语句分隔符,它也无法防止修改单个给定语句的SQL注入。
在本例中,如果
$id
的值为“1234 OR 1=1
”,则攻击者已更改了所有帐户的密码,可能包括特权用户。但没有涉及多个声明。在编写代码时,仍然需要注意安全问题。没有银弹可以防止SQL注入。
即使是查询参数也不是SQL注入的万能药。参数仅取代SQL表达式中的值。在许多常见情况下,仍然需要将应用程序变量插入到SQL字符串中。例如,参数化
IN()
predicate 时,或选择ORDER BY
表达式时。不要听那些说准备好的查询可以100%防止安全漏洞的人的话。另请参阅我的演示文稿SQL Injection Myths and Fallacies,或我的书SQL Antipatterns Volume 1: Avoiding the Pitfalls of Database Programming中关于SQL注入的章节。
3mpgtkmj4#
当您调用
mysql_query
或mysql_real_query
时,它无论如何都不会运行多个语句,因此语句分隔符并不重要。您可以使用enable multiple statements per query when you connect,但由于您试图避免该功能,请不要启用它。避免SQL注入的一个更好的选择是use prepared statements。从
mysql_stmt_init
和mysql_stmt_prepare
开始,用占位符表示语句的参数,然后在mysql_stmt_execute
之前用mysql_stmt_bind_param
填充参数。如果您不是直接调用API,那么您拥有的任何 Package 库都应该为准备好的语句提供支持。(如果它不支持它们,那么考虑切换到更好的 Package 器。)