【问题标题】:PDO prepared statements to store html contentPDO 准备语句来存储 html 内容
【发布时间】:2012-04-30 08:05:58
【问题描述】:

我正在寻找一种在准备好的语句中处理 HTML 内容的方法。

我的应用程序提供了一个基本的 WYSIWYG 编辑器,在用户保存内容后,我的脚本将 HTML 数据存储在 sqlite 数据库中。

但如果我使用的是准备好的语句,我的 HTML 会自然地转义。

这是我到目前为止所做的:

try {

    /* Create databases and open connections */
    $dbh = new PDO( 'sqlite:db/coaching.sqlite' );

    /* Set Error Mode for Exception Handling */
    $dbh->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );

    /* Prepare SQL Statement */
    $query = $dbh->prepare( "UPDATE Content SET Value=:value WHERE Token=:token" );

    /* Bind Param to Statement */
    $query->bindParam( ':token', $_POST['id'], PDO::PARAM_STR);
    $query->bindParam( ':value', $_POST['value'], PDO::PARAM_STR);

    /* Execute Query */
    $query->execute();

    /* Echo Data */
    echo $_POST['value'];

    /* Close connections to Database */
    $dbh = NULL;

}
catch( PDOException $e ) {

    /* Print Error-Messages */
    echo $e->getMessage();
}

【问题讨论】:

  • 你确定它被 bindParam() 转义了,而不是在从 HTTP 请求中检索 HTML 时?
  • 据我所知,用户输入会在 bindParam() 中自动引用。
  • @gearsdigital 准备好的语句不会转义变量。命令和变量同时但独立地传输到数据库。如果您看到您的数据在数据库中转义,还有另一个原因。例如。 magic_quotes 已打开。您可以在脚本中回显get_magic_quotes_gpc 以查看它们是打开还是关闭?
  • 你是对的。 magic_quotes 已启用,如果我禁用它,则不会逃脱。但只是为了理解:准备好的语句降低了 SQL 注入的风险?正确的?这是我第一次使用 PDO 和准备好的语句。
  • @gearsdigital 好的。我扩展了我的评论 - 请参阅下面的答案。

标签: php sqlite pdo prepared-statement


【解决方案1】:

准备好的语句不会转义变量。命令和变量同时但独立地传输到数据库。如果您看到您的数据在数据库中转义,还有另一个原因。例如。 magic_quotes 已打开。您可以在脚本中回显get_magic_quotes_gpc 以查看它们是打开还是关闭?如果它们打开,您可以使用different techniques 将它们设置为关闭。这样就可以解决问题了。

此外,在您发表评论之后,准备好的语句会执行prevent SQL injection attacks,因此您不必担心转义变量。可能难以理解的是准备好的语句的工作方式。假设您有一个查询:

$query = "SELECT `id` FROM `users` WHERE `login` = '" . $login . "' AND `password` = '" . $password ."'";

$login$password 按原样直接传递给查询。如果有人尝试将mylogin' -- 传递给$login,则查询变为:

$query = "SELECT `id` FROM `users` WHERE `login` = 'mylogin' -- ' AND `password` = 'anypassword'";

并被发送到数据库。这样,攻击者就可以访问任何帐户。

prepared statements 的作用是独立于查询传输查询参数。查询不是在将变量传输到数据库之前构建的。相反,变量以某种方式在查询旁边传输。它们在查询中被引用。这样查询就不会被有意或无意地欺骗。

使用prepared statement,示例$login将按原样传输,不会影响查询结构。

如果可以通过飞机运送乘客,而乘客实际上并未登机,那将被称为“准备飞行”:) 乘客将无法影响路线并劫持飞机。他们会在飞机降落时出现在目标机场。

【讨论】:

  • 你的飞机例子太棒了:) 谢谢!
  • 我在超级全局变量 $_POST$_GET 上遇到了同样的问题。我最终只去了没有这个“功能”的 PHP 5.4
【解决方案2】:

您是否尝试过存储已编码的数据?

http://php.net/base64_encode

http://php.net/serialize

如果在使用数据库之前/之后使用应该可以工作

【讨论】:

  • HTML 只是文本。在存储到数据库之前无需序列化。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-01-02
  • 1970-01-01
  • 1970-01-01
  • 2010-11-30
  • 2014-04-19
  • 2010-11-18
相关资源
最近更新 更多