php、mysqli函数安全问题

Posted

技术标签:

【中文标题】php、mysqli函数安全问题【英文标题】:php, mysqli function security issue 【发布时间】:2013-09-25 06:00:02 【问题描述】:

我有一个安全功能,但我有问题 我用 - mysqli

我用这个功能secure:

function secure ($string) 
  $string = htmlspecialchars($string);
  $string = strip_tags($string);
  $string = stripcslashes($string);
  $string = $mysqli -> real_escape_string($string);
  return $string;

问题在我看来是个错误:

致命错误:在非对象上调用成员函数 real_escape_string()

谢谢!

【问题讨论】:

变量$mysqli 不在此函数的范围内。将其作为参数传递function secure($string, $mysqli) 你还没有设置变量$mysqli。您要么需要将其作为参数传递给函数,要么使用global $mysqli; 声明它。 那就是杀戮和错误 放入数据库时​​不要使用htmlspecialchars(),渲染时应使用htmlentities() 通常不建议在将其存储到数据库之前调用htmlspecialchars()。这应该只在输出上完成,而不是在存储前进行修改。事实上,随后的strip_tags() 绝对没有,因为htmlspecialchars() 已经编码了<>。输入字符串中的任何标签在编码后都不再是标签。 【参考方案1】:

你可以做几件事。也许做类似的事情:

function secure($connection, $string) 
  return $connection->real_escape_string(htmlentities(strip_tags(stripcslashes($string))), 3, 'UTF-8');

我个人会将某些内容存储在安全页面上,例如:

function db()
  return new mysqli(/*arguments here*/);

然后执行以下操作:

function secure($string)
  $db = db();
  $str = $db->real_escape_string(htmlentities(strip_tags(stripcslashes($string))), 3, 'UTF-8');
  $db->close();
  return $str;
  

显然,这不是 javascript,所以你有一个范围问题。

【讨论】:

【参考方案2】:

如果你想让你的函数正常工作,你必须将 $mysqli 对象作为参数传递

像这样:

function secure ($string,$mysqli) 
  $string = htmlspecialchars($string);
  $string = strip_tags($string);
  $string = stripcslashes($string);
  $string = $mysqli -> real_escape_string($string);
  return $string;

我建议你,不要使用这个功能:

1- 结束杀戮和错误@Dagon 的评论。(同意) 2-既然您使用的是mysqli,那么当您可以使用准备好的语句时,您为什么要这样做? @barmar 的评论。(同意) 3- 放入数据库时​​不应使用 htmlspecialchars(),在呈现@bamar 评论时应使用 htmlentities()。(同意)

以上是我不使用的主要原因


您可以改用 Prepare Staments,an example from the manual
/* create a prepared statement */
$stmt = $mysqli->prepare("SELECT District FROM City WHERE Name=?");

/* bind parameters for markers */
$stmt->bind_param("s", $city);

/* execute query */
$stmt->execute();

/* bind result variables */
$stmt->bind_result($district);

/* fetch value */
$stmt->fetch();

printf("%s is in district %s\n", $city, $district);

/* close statement */
$stmt->close();

【讨论】:

【参考方案3】:

您为什么要回答这些问题,询问如何清理输入以便从外部数据构建 SQL 语句? 从外部数据构建 SQL 语句是危险的。

与其浪费时间担心如何想出另一个半途而废的“解决方案”,不如停下来穿上你的大程序员裤子,开始使用准备好的语句和绑定变量。

这里有一个很棒的答案,可以帮助您入门:How can I prevent SQL injection in php?

您也可以查看http://bobby-tables.com/php 了解其他示例。

在我看来,您仍然可以使用 Oracle 执行准备好的语句和绑定变量:http://php.net/manual/en/function.oci-bind-by-name.php 或通过 PDO http://php.net/manual/en/pdostatement.bindparam.php

【讨论】:

以上是关于php、mysqli函数安全问题的主要内容,如果未能解决你的问题,请参考以下文章

使用PHP / MySQLI / Apache时,在哪里安全地存储证书/密钥?

PHP中的Mysqli资源作为参数或全局

mysqli函数库的使用

在作为 GLOBALS 的函数中使用 Mysqli_connect 链接是不是安全?

PHP 和 MySQLi close()

php代码安全性问题