【问题标题】:SQL validation!SQL 验证!
【发布时间】:2010-06-05 12:42:59
【问题描述】:

我是 SQL 新手,所以这可能是个愚蠢的问题...

我有一个 PHP 表单,它填写了我的 SQL 表中的几个字段。我有这个代码:

$sql="INSERT INTO $tbl_name
(app_name, app_path, short_desc, full_desc)
VALUES ('$_POST[app_name]', '$_POST[app_path]',
'$_POST[short_desc]', '$_POST[full_desc]')";

但即使app_name 和app_path 都是NOT NULL 列,如果表单中这些字段中没有文本,则可以执行查询。

所以,我的问题是:

如果 NOT NULL 字段中没有文本,如何停止执行查询?

【问题讨论】:

  • 哦,看看 SQL 注入。
  • 您不应在查询中直接使用 $_POST 变量,因为这会使您面临 SQL 注入攻击。您可能想搜索 Google 并查看“准备好的语句”和“参数化查询”。

标签: php mysql sql


【解决方案1】:

不要这样,你正在用SQL injection vulnerabilities写代码。你也在让编程小仙女死去。

查看Prepared statements。之后,请在此处查看其他答案中的建议,先检查值。

【讨论】:

  • 这个。参数化查询是现在的情况,手工构建查询字符串是过去的事情。
  • 别担心。此表格仅供管理员使用。但是登录表单是安全的。还是谢谢。
  • @Filip:考虑到如果您在描述字段中输入撇号会破坏它,我想说这至少对管理员来说也是一种烦恼。此外,这不是让事情变得不安全的借口。最好始终坚持正确的做事方式,以免在真正需要的时候忘记它。
  • "此表格仅供管理员使用" => 我不记得我在哪里看到的,所以随便拿吧,但似乎大约 80% 的真实公司数据都以这种方式销毁了是有效的、已登录的、可能心怀不满的员工。不要信任已登录的用户。也许甚至不是你自己:P
  • +1 @Wrikken。当人们说“它仅供内部用户使用”时,我讨厌它。我也厌倦了与具有这些完全相同问题的供应商软件打交道。有时我觉得应该有关于销售无视安全最佳实践的软件的法律。
【解决方案2】:

您可以在尝试执行查询之前测试这些值:

if (empty($_POST['app_path']))
{
    // Error.
}

另请注意,您的代码可能容易受到 SQL 注入攻击。您可以使用mysql_real_escape_string 来保护自己免受这种攻击:

$sql= sprintf("INSERT INTO $tbl_name
               (app_name, app_path, short_desc, full_desc)
               VALUES ('%s', '%s', '%s', '%s')",
               mysql_real_escape_string($_POST['app_name']),
               mysql_real_escape_string($_POST['app_path']),
               mysql_real_escape_string($_POST['short_desc']),
               mysql_real_escape_string($_POST['app_full_desc']));

【讨论】:

  • $_POST[app_path] 将引发至少一个 E_NOTICE,因为您忘记引用 app_path,如果未定义值,可能还会引发另一个。你应该做的是empty($_POST["app_path"])
  • @Matti Virkkunen:太好了!我很惊讶这里没有其他人建议过。
  • 查看filter_input 以访问 _POST/_GET 等,但请务必指定过滤器 - 默认不过滤。
【解决方案3】:

顺便说一句,空字符串和 NULL 不是一回事。 http://dev.mysql.com/doc/refman/5.0/en/working-with-null.html

并在执行查询之前验证变量。

【讨论】:

    【解决方案4】:

    它们可能是空白/空字符串,空字符串与NULL不同

    但是你有更大的问题,你的代码容易受到SQL注入

    【讨论】:

      【解决方案5】:

      空字符串不是null,所以即使你插入它也不会发生任何不好的事情。但是,如果您真的想中止,那么与@Jan 的解决方案相同,但是我不能赞成它,因为他没有在与escaping user's stringsSQL injection attacks

      UPDATE 现在他做到了:) 无论如何,看到了吗?问一个问题,让每个人回答另一个更有价值的问题! :)

      【讨论】:

        【解决方案6】:
        if ($app_name != "" && $app_path != "")
            $sql="INSERT INTO $tbl_name (app_name, app_path, short_desc, full_desc) VALUES ('$_POST[app_name]', '$_POST[app_path]', '$_POST[short_desc]', '$_POST[full_desc]')";
        else { /* do something */ }
        

        在运行插入查询之前使用mysql_real_escape_string() 清理输入。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2015-01-26
          • 2020-02-28
          • 2012-09-25
          • 1970-01-01
          • 1970-01-01
          • 2010-10-05
          • 2023-03-22
          • 1970-01-01
          相关资源
          最近更新 更多