【问题标题】:Preventing MS SQL Injections with CodeIgniter使用 CodeIgniter 防止 MS SQL 注入
【发布时间】:2017-11-11 09:38:54
【问题描述】:

我想找到一种最佳方法来减轻在 CodeIgniter 框架中开发的 Web 应用程序中的 SQL 注入(Web 应用程序使用带有 ODBC 连接的 MS SQL 后端数据库)。

假设我有一个这样的简单易受攻击的代码:

$this->db->query("SELECT * FROM users WHERE Login = '".$_GET['name']."'");

此查询显然易受通过 HTTP GET 参数“name”的 SQL 注入攻击。

我已阅读 CodeIgniter 文档以及我可以在网上找到的所有内容,以了解如何在 CodeIgniter 中缓解这种简单的 SQL 注入,并且我尝试了以下所有选项:

选项 1:

$this->db->query("SELECT * FROM users WHERE Login = ".$this->db->escape($_GET['name']));

选项 2:

$this->db->select("*")->from("users")->where('Login', $_GET['name'])->get();

选项 3:

$query = "SELECT * FROM users WHERE Login = '?'"; 
$this->db->query($query, array($_GET['name']));

选项 4:

$query = "SELECT * FROM users WHERE Login = ?"; 
$this->db->query($query, array($_GET['name']));

我震惊地发现,所有上述四个选项都与初始查询一样容易受到 SQL 注入的影响。我想知道 CodeIgniter 从安全角度来看是否设计得如此糟糕,或者我是否遗漏了一些重要的配置。

在这种情况下,有什么概念方法可以防止 CodeIgniter 中的 SQL 注入?

【问题讨论】:

  • 您究竟是如何发现所有选项都存在漏洞的?前两个甚至都不起作用,第三个只是做第四个的错误方式……而第四个既是唯一有效的“选项”,也是唯一安全的选项。
  • 选项 2 有什么问题?
  • 我已经对应用程序进行了渗透测试,其中包含我帖子中提到的易受攻击的代码行。现在,我想提出解决方案如何解决它。我测试了帖子中的所有四个选项,它们都对我有用——但这实际上并不重要。如果我使用应该是安全的选项 4 并提交以下 HTTP GET 参数 ?name=nonexistent' OR 1=1 则应用程序会引发以下错误:[Microsoft][ODBC SQL Server Driver][SQL Server]Unclosed quotes在字符串 '' 之后标记。 SELECT * FROM auth_user WHERE Login = '不存在' OR 1=1'
  • 你确定,第四个选项不安全吗?第三个选项实际上不应该工作。你应该写? 而不是'?'。这样做的原因是整数值不需要转义,但字符串值会被 CodeIgniter 自动转义,然后用引号括起来。此外,这个问题可能与stackoverflow.com/questions/5857386/… 重复
  • 我打开了这个问题,因为stackoverflow.com/questions/5857386/… 中的任何内容都不适合我。我用选项 4 替换了原始易受攻击的代码,并且我能够执行与以前完全相同的 sql 注入。也许它与后端 MS SQL 和 ODBC 有关。不太确定...

标签: php codeigniter security sql-injection


【解决方案1】:

好的,经过几个小时的努力,我自己找到了答案。

3.1.0 之前的 CodeIgniter ODBC 驱动程序中存在 SQL 注入漏洞。因此,即使从安全角度来看,编码风格(查询绑定)是正确的(如选项 4 所示),应用程序仍然容易受到用户提供的输入的 SQL 注入攻击。

我通过并排安装 CodeIgniter 3.0.6 和 3.1.0 运行相同的查询来验证这一点。 CodeIgniter 3.0.6 中的代码仍然容易受到 SQL 注入的影响,而在 CodeIgniter 3.1.0 中运行的代码则不然。

CodeIgniter 更改日志https://www.codeigniter.com/userguide3/changelog.html

所以为未来吸取了教训。永远记得检查框架版本。

【讨论】:

  • ... 并定期更新。不要将其保留在 3.1.0 - 它是修复此特定问题的版本,但不是最新版本。
【解决方案2】:
  • 检查每个用户输入的数据类型以及正则表达式适用的地方(永远不要相信用户输入)
  • 使用准备好的语句

这是很多工作,尤其是如果您的应用程序状况不佳,但这是获得良好安全级别的最佳方式

另一种方式(我不建议这样做)可能是使用 mod_security 或 WAF 进行虚拟修补以过滤注入尝试,但首先:尝试编写健壮的应用程序(虚拟修补似乎是一种懒惰的修复方式但实际上也需要大量的工作和测试,并且真的应该只在已经很强大的应用程序代码之上使用)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-11-16
    • 2015-09-27
    • 1970-01-01
    • 2013-05-01
    相关资源
    最近更新 更多