【问题标题】:Is this code sufficient to protect me from SQL injection attacks, and PHP injection attacks?这段代码是否足以保护我免受 SQL 注入攻击和 PHP 注入攻击?
【发布时间】:2012-04-14 16:02:58
【问题描述】:

这段代码是否足以保护我免受 SQL 注入攻击和 PHP 注入攻击?

我在函数的包含文件中有这个函数:

function strclean ($string) {
  $outstr = '';
  if (strlen ($string) > 0) {
    $ix = 0;
    $char = substr ($string, $ix, 1);
    // strip leading spaces
    while ($char == ' ') {
      $ix = $ix + 1;
      $char = substr ($string, $ix, 1);
      }
    // disarm naughty characters
    while ($ix < strlen ($string)) {
      $char = substr ($string, $ix, 1);
      if ($char == '<') $char = '&lt;';
      else if ($char == '>') $char = '&gt;';
      else if ($char == '"') $char = '&quot;';
      else if ($char == '&') $char = '&amp;';
      else if ($char < chr(20)) $char = '';
      $outstr = $outstr . $char;
      $ix = $ix + 1;
      }
    // strip trailing spaces
    while (substr ($outstr, strlen ($outstr) - 1, 1) == ' ' && strlen ($outstr) > 0) {
      $outstr = substr ($outstr, 0, strlen ($outstr) - 1);
      }
    $outstr = mysql_real_escape_string ($outstr);
    }
  return $outstr;
  }

稍后在我的页面中,我从表单输入返回了各种字符串,例如这个例子:

$username = strclean ($_POST['username']);
$password = strclean ($_POST['password']);

甚至后来,我有以下 SQL:

$result = mysql_query ('SELECT * FROM users WHERE 
  username = "' . $username . '"', $dbconn) or die (mysql_error());

我没有在查询中同时搜索用户名和密码。在这之后的几行,我检查了一个有效的密码,如下所示:

if ($rowsfound == 1) {
  $userrow = mysql_fetch_array ($result);
  $userword = $userrow ["password"];
  if ($userword == $password) {
     // logon
     }
  else {
    // incorrect password
    }
  }
else if ($rowsfound == 0) {
  // unknown user
  }  
else {
  // something strange happened!  possible sql injection attack?
  }

【问题讨论】:

标签: sql code-injection


【解决方案1】:

一般规则是拒绝所有内容并仅允许通过有效字符,而不是删除您认为无效的内容。 最重要的方面是你之后如何处理这些字符串。如果你后面有一行说: tsql = "SELECT * FROM Users WHERE Username='" . $username . "' AND " 那么这是主要的风险领域,尽管mysql_real_escape_string 应该避免这种情况。

通过使用允许将参数传递到数据库的库或功能,永远不会有任何 sql 注入,因为数据库参数无法解释为 TSQL,只有 PHP/Javascript 注入是可能的。 基本上,将bind_param 函数视为唯一真正的保护。

每当在屏幕上显示数据时,请考虑使用htmlspecialchars() 之类的方法将其转换为 HTML。如果您以后需要未转义的内容,则存储已转义的内容是没有意义的,只要您始终将其视为原始数据,数据库中的原始数据就不会构成任何风险。

总而言之,您列出的代码可能会或可能不会减少注入,但组合太多,无法排除所有可能性,包括用户使用单引号(您只是替换双引号)等方面。 所有用户输入数据都有潜在危险。随意将其原始存储,但无论何时使用它,请确保使用上述选项之一保护您的操作。

我的 PHP 现在有点生疏了,但完全相同的规则适用于 SQL Server、Oracle、.NET、Java 任何其他数据库/语言。

【讨论】:

  • 后来,我有一行说:$result = mysql_query ('SELECT * FROM users WHERE username = "' . $username . '"', $dbconn); 我不在查询中搜索密码。几行之后,我根据数据库上的密码测试提供的密码。
  • 是的,这正是要避免的事情!如果有人在您的复杂逻辑中发现缺陷,他们可以将任何语句注入该 SQL。查看 mysql lib 中的 bind_param 函数并使用它们。然后根本不需要转义。从理论上讲,您可以假设 mysql_real_escape_string 可以防止这种情况发生,但我从不冒险。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-09-15
  • 2020-10-15
  • 2015-11-30
  • 1970-01-01
  • 2015-10-03
  • 2019-08-10
  • 2013-05-21
相关资源
最近更新 更多