【问题标题】:MySQLi and PHP allow special characters in form submission, but not SQL insert? [duplicate]MySQLi 和 PHP 允许在表单提交中使用特殊字符,但不允许 SQL 插入? [复制]
【发布时间】:2015-10-03 14:38:57
【问题描述】:

我一直在为我在网站上使用的“联系我们”表单编写一个 PHP 脚本,以允许用户对该网站发表评论。它有几个字段,包括一个名称字段和一个用于 cmets 的文本区域。用户提交表单后,评论被输入数据库,然后查询最近的五个 cmet 并将它们显示在网站上。但是,用户目前无法在名称字段或 cmets 区域中输入撇号 (') 并使其正确显示。

这是事件的顺序:

"User Submit -> Prepare SQL -> Insert Record -> Query Database -> Return recent Comments"

目前,这是我为 PHP 所拥有的:

//Function that will trim the input, and run it through a small security check
function test_input($input)
{
    $input = trim($input);
    $input = stripslashes($input);
    $input = htmlspecialchars($input);
    return $input;
}

$name = test_input($_POST["txtName"]);
$comments = test_input($_POST["txtComments"]);

//Prepared statement to insert a new Contact record
$stmt = $conn -> prepare("INSERT INTO tableName (name, comments) VALUES (?, ?)");

//Create the parameters of the prepared statement
$stmt -> bind_param("ss", $param_name, $param_comments);

//Set the parameters of the statement, running them through a security check
$param_name = mysqli_real_escape_string($conn, $name);
$param_comments = mysqli_real_escape_string($conn, $comments);

//Execute the prepared statement
$stmt -> execute()

如您所见,我通过htmlspecialchars() 函数和mysqli_real_escape_string() 函数运行变量。但是,当我运行该函数时,我仍然得到一个奇怪的输出。


输入

Name with Apostro'phe
I'm happy with the "/" and "\" of the present.

它的外观...

...数据库

Name with Apostro\'phe
I\'m happy with the "/" and the "" of the present.
  • 我理解"来自htmlspecialchars函数,并认为\'来自mysqli_real_escape_string()函数。

..网站评论部分(从数据库填充)

Name with Apostro\'phe
I\'m happy with the "/" and the "" of the present.
  • 这里与\' 相同。如何获取它,以便在从数据库中查询后在 HTML 中重新显示时,撇号正常显示?

但是,这不是我想要的。当它显示在 cmets 部分(从数据库中查询后)时,我希望它显示为用户输入的内容。我并不关心它在数据库中的外观,只要它在查询返回到 HTML 以填充列表时正确显示即可。


我应该怎么做才能让用户在他们的名字/cmets中输入撇号,并在从数据库返回后显示出来;但同时,不冒SQL注入的风险?我查看了几个相关问题,但没有找到任何可以回答我的问题的内容。

MySQL/PHP: Allow special characters and avoid SQL injections

  • 我已经尝试过这篇文章中的方法,但没有成功

php - Allowing special characters in form submit

  • 我不需要这样的东西,只需要撇号

如果我需要澄清任何事情,请告诉我!

【问题讨论】:

  • 用户html_entity_decode 用于显示信息可能吗? php.net/manual/en/function.html-entity-decode.php
  • 您也可以在将信息写入数据库之前使用htmlentities()。不确定是否需要,因为您已经在使用htmlspecialchars()
  • @Maximus2012 我认为这没有必要,因为它已经正确显示了报价。但是,它是不正确的撇号。 php手册似乎并没有表明这个函数无论如何都包含撇号。
  • 你可以试试这两个功能,看看是否有效?

标签: php html forms mysqli htmlspecialchars


【解决方案1】:

您正在使用带有预准备语句的占位符。手动转义文本是完全没有必要的。作为占位符系统的一部分,DB 已经在进行自己的内部转义,因此您的转义只是添加了额外的转义层,将被输入到表中。

例如

name                   = "Miles O'Brien";
manual escape         -> "Miles O\'Brien";
placeholder escape    -> "Miles O\\'Brien";
stored in database    -> "Miles O\'Brien";
retrieved from db     -> "Miles O\'Brien";
displayed to user     -> "Miles O\'Brien";

如果您删除手动转义,那么突然一切都按预期工作:

name                   = "Miles O'Brien";
placeholder escape    -> "Miles O\'Brien";
stored in database    -> "Miles O'Brien";
retrieved from db     -> "Miles O'Brien";
displayed to user     -> "Miles O'Brien";

【讨论】:

  • 我已经删除了mysqli_real_escape_string() 函数,它似乎正在工作。但是,这不是仍然容易受到攻击吗?我之前在阅读该问题时有点困惑,因为有人告诉我总是使用真正的转义字符串函数。
  • cargo cult 编程...阅读bobby-tables.comstackoverflow.com/questions/60174/… 以了解问题的真正原因,而不是盲目地应用任何“解决方案”。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-12-10
  • 1970-01-01
  • 2013-09-16
相关资源
最近更新 更多