Достаточно ли этого кода для защиты от атак SQL-инъекций и PHP-инъекций? - PullRequest
0 голосов
/ 31 марта 2012

Достаточно ли этого кода, чтобы защитить меня от атак с использованием 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?
  }

1 Ответ

1 голос
/ 31 марта 2012

Общее правило состоит в том, чтобы запретить все и пропустить только допустимые символы, а не удалять то, что вы считаете недействительным. Наиболее важным аспектом является то, что вы делаете с этими строками впоследствии. Если у вас есть строка позже, говоря: 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 и любой другой базе данных / языку.

...