5

我有一个托管在共享主机上的网站。他们安装了 php 5.2.13。

我知道 SQL 注入的漏洞,我想阻止它。

所以我想使用 PDO 或 mysqli 来防止它。

但是我phpinfo();以前查看托管环境php设置信息的时候,
发现里面没有PDO的mysql驱动,里面也没有对mysqli的支持。

所以我想知道使用旧的 mysql_* 函数(以及类似的函数mysql_real_escape_string)是否安全。

我在 SO 上看了这个,但它对我没有多大帮助。 当 mysqli 和 PDO 不可用时,可以使用准备好的语句吗?

更新:

我忘了提到大多数查询都很简单。没有使用任何表单,因此不会使用用户输入来进行查询。所有查询都将使用必要的参数进行硬编码,并且一旦设置就不会更改。

4

3 回答 3

4

不会。缺乏更安全的解决方案绝不是退回到更不安全或更易受攻击的解决方案的正当借口。

你最好找到一个不同的托管服务提供商,即使在他们的共享托管包中也不会禁用任意 PHP 功能。哦,尝试获得一个使用 PHP 5.3 的,或者如果可以的话,使用 PHP 5.4 更好。

于 2012-11-06T08:52:52.230 回答
1

如果您对始终使用mysql_real_escape_string()所有用户提供的输入非常严格,那么我认为您应该免受准备好的语句保护您免受任何 SQL 注入的影响。

你在这方面有多完美?我敢打赌,大多数缓冲区溢出漏洞都是由认为自己擅长检查输入的程序员创建的......

于 2012-11-06T08:57:52.027 回答
0

一个很好的方法是实现一个 Wrapper 类以使用 mysql_* 函数,并使用一些方法来创建准备好的语句。

这个想法是您必须在查询中传递强类型参数。

例如,这是一段具有一般思想的代码。当然,它需要更多的工作。但如果实施得当,这可以防止 SQL 注入攻击。

您还可以搜索已经实现该功能的 3rd 方库,因为这很常见。

<?php

class MyDb
{
  protected $query;

  public function setQuery($query)
  {
    $this->query = $query;
  }

  public function setNumericParameter($name, $value)
  {
    if (is_numeric($value)) // SQL Injection check, is the value really an Int ?
    {
       $this->query = str_replace(':'.$name, $value);
    }
    // else, probably an intent of SQL Injection
  }

  // Implement here the methods for all the types you need, including dates, strings, etc

  public function fetchArray()
  {
     $res = mysql_query($this->query);
     return mysql_fetch_array($res);
  }
}


MyDb $db = new MyDb();
$db->setQuery('SELECT * FROM articles WHERE id = :id');
$db->setNumericParameter('id', 15);

while ($row = $db->fetchArray())
{
// do your homework
}
于 2012-11-06T08:59:49.220 回答