【问题标题】:Secure all post and get data in framework php [duplicate]在框架php中保护所有帖子并获取数据[重复]
【发布时间】:2014-05-13 21:07:02
【问题描述】:

我刚刚有了“preSecure”来自 $_post 和 $_get 的所有用户输入数据的想法。但我想知道这是否是一种好的做法,并希望对此有所了解。这是我想出的:

function clean_str($str){
    return preg_replace('#[^a-z_ 0-9@.-]#i', '', $str);
}

if ($_POST){
    foreach ($_POST AS $key => $val){
        $_POST[$key] = clean_str($val);
    }
}

if ($_GET){
    foreach ($_GET AS $key => $val){
        $_GET[$key] = clean_str($val);
    }
}

这个 sn-p 将简单地在每个 http 请求的开头运行。可以开发 clean_str 函数以允许其他字符和替换字符等(这只是一个示例)。但我认为第一个目标是简单地防止 sql 注入。我现在用这种方法看到的唯一不好的事情是你的“插件”是否需要从用户输入发送 sql 命令。上面的方法当然可以包装在一个函数中,并在需要时被调用。 Post 和 Get 是全局变量,所以这不是问题。

我实际上正在编写我自己的框架(还有很多工作),如果我能够完成它,我将发布它。问题是我经常看到新手开发人员在数据库查询中添加 $_POST['userinput'] 。上面的代码应该可以做到这一点。嗯,这就是我所做的一些背景以及我提出这个问题的原因。

我很高兴听到您的想法。对于 Stack Overflow 来说,这可能不是最好的问题,我想我想就这种方法展开更多讨论,以分享想法和意见。但是,要对此提出我的问题,它应该符合:是否有任何其他方法比这更快或更可扩展,或者等于这个,或者另一个函数可以补充这种方法?这种方法是好的做法吗?是否可以覆盖 post 的全局变量并获取上述数据?

我知道上面的代码不是面向对象的,但它是关于在运行检查之前自动清理用户输入数据的方法。我认为这将节省大量代码和头痛。

请与我分享您的想法。由于 cmets 在 Stack Overflow 上受到限制,如果您给这个表格带来新的想法,如果您回复为答案,我将不胜感激。评论是对这种情况下的具体想法/答案进行评论。

【问题讨论】:

  • 如果您想让 Thomas O'Leary 先生在表格中输入他的姓名,或者让某人输入网址,这没什么用处
  • 我从来没有看到这一点。你需要知道你期待什么数据。如果您排除几乎所有内容,则很难在 SO 上发布代码。
  • 取决于您如何制作 clean_str 函数。你可以在那个函数中使用 mysql_real_escape_string 并且你很好。
  • 您应该将clean_str 重命名为corrupt_str。绝对不需要删除preventing SQL injectionsany 字符。使用经过验证的技术,如准备好的语句,一切都很好。
  • 原则上,这不是一个可怕的想法。然而,在现实世界中,您遇到不想以这种方式“清理”字符串的情况。您确实需要根据具体情况处理字符串“清理”。

标签: php security post get sql-injection


【解决方案1】:

首先如果用户尝试注入一个数组然后它会生成一个通知,你应该在调用它之前检查一个字符串,否则:

Notice: Array to string conversion 

但老实说,您只是在创建自己的魔术引号版本,这不是一个好主意。

简单且更好的解决方案是使用预准备语句,以及 PDO 或 MySQLi。

PHP Website 上的一篇关于魔术引用的帖子很好地总结了它:

不推荐使用魔术引号的真正原因是,一种千篇一律的转义/引用方法是错误的,而且非常危险。不同类型的内容具有不同的特殊字符和不同的转义方式,并且在一个内容中起作用的内容往往会在其他地方产生副作用。任何此处或其他任何地方的示例代码,假装像魔术引号一样工作——或者对 HTML、SQL 或其他任何东西进行类似的转换——同样是错误的,同样是危险的。

魔术引号不是为了安全。他们从来没有。这是一件很方便的事情——它们的存在使得 PHP 新手可以摸索并最终编写一些有点工作的 mysql 查询,而无需了解如何正确转义/引用数据。他们防止一些意外的语法错误,就像他们的工作一样。但它们不会阻止恶意和半知识的攻击者破坏 PHP noob 的数据库。而那个可怜的菜鸟甚至可能永远不知道他的数据库现在是如何消失或为什么消失了,因为魔术引号(或他那漂亮的“我要逃避一切”功能)给了他一种虚假的安全感。他不必学习如何真正处理不受信任的输入。

数据应该在您需要转义的地方以及将要使用的域中转义。 (mysql_real_escape_string -- 不是添加斜杠! -- 用于 MySQL(除非你有线索并使用准备好的语句),htmlentities 或 htmlspecialchars 用于 HTML 等)其他任何事情都注定要失败。

【讨论】:

    【解决方案2】:

    这不是一个好方法。防止 MySQL 注入不仅仅是确保某些字符被转义的问题——即使您尝试以这种方式进行清理,您仍然可以进行大量攻击。当您可以使用准备好的语句而不再担心需要检查的所有事情时,似乎您使事情变得过于复杂。 http://www.php.net/manual/en/mysqli.prepare.php

    【讨论】:

    • 我正在学习 pdo,还没有尝试过准备语句。如果我在 pdo 准备好的语句中运行 $_POST['userinput'] ,即使 userinput 类似于“test ' test”,它会起作用吗? prepare 语句会自行转义字符串吗?
    • @Medda86 如果它是任何东西都会起作用....即使它是“-- Test ' " ' '" "'drop table " "\ /' "
    猜你喜欢
    • 1970-01-01
    • 2012-10-12
    • 2019-07-16
    • 1970-01-01
    • 2016-03-21
    • 2022-01-15
    • 1970-01-01
    • 2018-04-25
    • 2013-04-19
    相关资源
    最近更新 更多