我已经建立了一个即将上线的网站,我有几个关于防止SQL注入的问题,我知道如何使用mysqli_real_escape_string,但我只是想知道我是否必须在SQL语句的所有变量上使用mysqli_real_escape_string,我是否也必须在执行select语句时使用它,还是只在insert update和delete语句时使用它?还有什么其他安全措施,你会建议我实施之前,我把网站的生活,提前感谢任何帮助!

推荐答案

任何查询都可以被注入,无论是读还是写、持久还是暂时.注入可以通过结束一个查询并运行一个单独的查询(可能是mysqli)来执行,这会使预期的查询变得无关.

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

SELECT col1 FROM t1 WHERE col2 = ?

?是参数的占位符.使用mysqli,可以使用prepare创建准备好的语句,使用bind_param将变量(参数)绑定到参数,并使用execute运行查询.你根本不需要净化争论(事实上这样做是有害的).mysqli是为你做的.整个过程将是:

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

parameterized queryprepared statement之间还有一个重要的区别.本声明虽然准备好了,但没有参数化,因此容易被注入:

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

总结一下:

  • All个查询应该正确参数化(除非它们没有参数)
  • 对一个问题的All个论点,无论其来源如何,都应尽可能地予以敌视

Mysql相关问答推荐

如何在考虑另一表的值的情况下计算一列的值

MySQL过滤食谱上的多对多 - 成分表

MySQL REGEXP 在没有 BINARY 模式的情况下区分大小写?

在 MySQL 中为多列创建索引以进行查询优化

mysql - 如何加入表中的动态列

MySQL按连续值和计数分组

MySQL - 计算行重复的最大计数

MySQL查询根据同一表中其他字段的值更新表中的字段

如何将 MySQL 5.7 更新到新的 MySQL 8.0?

无法从 mysql 工作台导出我的数据库

Sequel Pro 和 MySQL 连接失败

MySQL 8.0 上的 phpMyAdmin

Amazon RDS Aurora 与 RDS MySQL 与 EC2 上的 MySQL?

脚本超时,如果要完成导入,请重新提交相同的文件,导入将恢复

不支持扫描,将 driver.Value 类型 []uint8 存储到 *time.Time 类型中

带有 OuterRef 的简单子查询

Hibernate 生成的 DDL 中的无效语法错误“type=MyISAM”

Spring Boot JPA 使用 Hibernate 在 TABLE 中插入大写名称

等于 (=) 和具有一个文字值的 IN 之间的性能差异

为 DATE 或 DATETIME 设置默认值时 MySQL 出错