【问题标题】:Using mysql's INTERVAL with prepared statement使用 mysql 的 INTERVAL 和准备好的语句
【发布时间】:2019-12-19 10:49:49
【问题描述】:

我准备我的数据库请求以防止使用扩展名 Mysqlnd 进行 SQL 注入。 像这样的请求在我的网站上工作:

SELECT a, b FROM table where a = ?;

下一个请求在我的网站上不起作用:

SELECT a, b FROM table where b > DATE_SUB(CURRENT_TIMESTAMP(),INTERVAL ? ?);

错误日志:PHP 致命错误:在...中的非对象上调用成员函数 execute() 这是因为请求的语法错误。

当我在我的 DB IDE 中尝试它时,双问号算作 1 而不是 2 个参数。

我该如何解决这个问题?

【问题讨论】:

  • 我没有测试过,但我假设你不能参数化查询的 DAY/WEEK/... 部分
  • @NigelRen 没有真正的帮助,因为我想用我的参数进行选择,如果它是 MONTH/DAY/HOUR/...

标签: php mysqli bindparam


【解决方案1】:

使用占位符,您只能绑定数据文字,即字符串和数字。

INTERVAL 接受两个参数,expressionunit

虽然expression 部分是一个数字并且可以完全绑定,但unit 部分是一个关键字,因此无法绑定。因此,您只能将其列入白名单。这是我写的white-listing function,可以帮助解决这个问题。

$unit = white_list($_GET['unit'], ["DAY","MINUTE","SECOND"], "Invalid time unit name");
$sql = "SELECT a, b FROM table where b > DATE_SUB(CURRENT_TIMESTAMP(),INTERVAL ? $unit)";

不是很整洁,但至少简洁安全。

【讨论】:

  • 或者用PHP原生的in_array函数代替white_list
  • $unit = in_array($_GET['unit'], ["DAY","MINUTE","SECOND"]) ? $_GET['unit'] : "Invalid";
  • $unit = "Invalid" 会导致 SQL 错误
  • 代替: "Invalid" 你可以 exit() die() throw new error etc
  • 所以它不再是“只是 in_array()”,而是一段 PHP 代码。然后,为简单起见,您可能希望将其包装在用户定义的函数中。并称之为 white_list()
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-09-16
  • 2013-09-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-12-18
  • 1970-01-01
相关资源
最近更新 更多