【问题标题】:Is this a secure method to insert form data into a MySQL database? [duplicate]这是将表单数据插入 MySQL 数据库的安全方法吗? [复制]
【发布时间】:2012-03-26 07:51:37
【问题描述】:

可能重复:
How can I prevent SQL injection in PHP?

这是 w3schools.org 上的示例:

HTML 表单:

<html>
    <body>
        <form action="insert.php" method="post">
            Firstname: <input type="text" name="firstname" />
            Lastname: <input type="text" name="lastname" />
            Age: <input type="text" name="age" />
            <input type="submit" />
        </form>
    </body>
</html>

文件插入.php:

<?php
    $con = mysql_connect("localhost","peter","abc123");
    if (!$con)
    {
        die('Could not connect: ' . mysql_error());
    }

    mysql_select_db("my_db", $con);

    $sql="INSERT INTO Persons (FirstName, LastName, Age)
          VALUES
          ('$_POST[firstname]','$_POST[lastname]','$_POST[age]')";

    if (!mysql_query($sql,$con))
    {
        die('Error: ' . mysql_error());
    }
    echo "1 record added";

    mysql_close($con)
?>

我已阅读此处的其他问题,但找不到直接答案,因为大多数问题要复杂得多。

我查看了 How can I prevent SQL injection in PHP?,但对如何修改它有点困惑:

$preparedStatement = $db->prepare('INSERT INTO table (column) VALUES (:column)');

$preparedStatement->execute(array(':column' => $unsafeValue));

假设我使用上面的 HTML 表单并想将字段 'firstname' 中的数据插入到数据库中,它应该是这样的吗?还是我应该修改column?:

$preparedStatement = $db->prepare('INSERT INTO table (column) VALUES (:column)');

$preparedStatement->execute(array(':column' => $firstname));

【问题讨论】:

  • 那么,你到底有什么问题?
  • 我怎样才能使这种方法安全?

标签: php mysql


【解决方案1】:

您提供的示例将帖子变量插入到数据库中,而没有首先分析它们是否存在恶意用户输入。在使用类型转换、转义/过滤函数、准备好的语句等与数据库交互之前使用它们。

要遵循的一般规则是永远不要相信用户输入。永远!

查看:Best way to stop SQL Injection in PHP

针对您的问题,以下是您如何使用 PDO 准备好的语句来处理整个表单。

$stmt = $db->prepare('INSERT INTO Persons (FirstName, LastName, Age) VALUES (:first_name, :last_name, :age)');

$stmt->execute(array(':first_name' => $first_name,':last_name' => $last_name, ':age' => $age));

如果您只想按照您的要求在记录中插入一列,则语法为:

$stmt = $db->prepare('INSERT INTO Persons (FirstName) VALUES (:first_name)');

$stmt->execute(':first_name', $first_name);

【讨论】:

    【解决方案2】:

    没有。

    高度容易受到 sql 注入攻击。

    我建议不要使用mysql_real_escape_string,而是使用准备好的语句。

    【讨论】:

    • 好的,谢谢。关于如何修改它以使其安全的任何提示?
    • 你应该使用准备好的语句。
    【解决方案3】:

    【讨论】:

      【解决方案4】:
      $magic_quotes_active = get_magic_quotes_gpc();
      $real_escape_string_exists = function_exists('mysql_real_escape_string');
      
      function escape_value($sql) {
          if ($real_escape_string_exists) {
              if($magic_quotes_active) {
                  $sql = stripslashes($sql);
              }
              $sql = mysql_real_escape_string($sql);
          } else {
              if(!$magic_quotes_active) {
                  $sql = addslashes($sql);
              }
          }
          return $sql;
      }
      

      这被认为是一种将内容插入数据库的非常安全的方法。使用返回的$sql 作为您的查询!

      【讨论】:

      • 为什么投反对票?这是由 Nova Fabrica 的作者实现的! novafabrica.com">
      • 我没有投反对票 - 但为了清楚起见,此函数只能用于转义单个值,而不是整个 SQL 字符串。
      • 不知道 Nova Fabrica 的作者是谁,但他显然不知道
      • @shrapnel,大谈特谈,他恰好是 Kevin Skoglund,是一位出色的 PHP 程序员。你对他的功能有什么问题?
      • 首先,我删除了这个不相关的链接。接下来,这个函数的主要问题是将魔术引号与转义字符串混合在一起。魔术引号是一个站点范围的问题,与 SQL 无关。它会破坏任何数据,而不仅仅是 SQL 字符串(例如 cookie)。因此,无论有任何 SQL 活动,都必须在引导程序中关闭或删除魔术引号。虽然 mysql_real_escape_string 的用途非常有限 - 它只能用于转义 SQL 字符串。看 - 这是完全不同的事情,不能混合它们。
      猜你喜欢
      • 2019-05-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-01-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多