使用Zend Framework的SQL模型时的SQL注入漏洞


15

连接表时,我使用Zend Framework的SQL模型。例如,我修改了我的实际代码,但我想您会明白的:

$this->getSelect()->join(
                      array('sections' => $sectionsTableName),
                      'main_table.banner_id = pages.banner_id',
                      array()
                    )
                  ->where("sections.section= '$section' OR sections.section = '0' OR (sections.section = '6' AND ? LIKE main_table.url)",$url)
                  ->group('main_table.banner_id'); 

该页面加载了ajax,并且$ section参数作为GET参数(www.example.com/controllerName/index/display/3?paremeter1=example&section=www.example2.com)发送。

如果有人执行以下操作,这就是问题所在:

www.example.com/controllerName/index/display/3?paremeter1=example&url=(SELECT 3630 FROM(SELECT COUNT(*),CONCAT(0x7170786a71,(SELECT (ELT(3630=3630,1))),0x717a716b71,FLOOR(RAND(0)*2))x FROM INFORMATION_SCHEMA.CHARACTER_SETS GROUP BY x)a)

这样,用户可以转储整个数据库。不会显示数据,但是SQL仍会执行转储,这可能导致sql重载。

问题:

  1. 防止这种情况的最佳方法是什么?
  2. 现在,我为以前的客户感到担忧。使用此代码是否可以采取更大的风险措施,例如延迟或更改表?我猜不是因为您不能在SELECT中放入除SELECT之外的任何其他语句,所以DELETE将产生sql语法错误。我对吗?

更新: 我的示例不是对SQL注入的正确说明,因为存在'符号围绕$ sections,因此将无法进行注入。无论如何,当期望整数值并且不过滤整数输入时,这都是可能的。见下面我的评论。


1
您可以使用:甚至就您而言$db = Mage::getSingleton('core/resource')->getConnection('core_read');$db->quote()也可以使用 $db->quoteInto。如果$this是资源,则可以执行:如果是资源,$this->getConnection('core_read')->quoteInto()则可以执行:$this->getResource()->getConnection('core_read')->quoteInto()。遵循这些原则。如果这样可以帮助您实现目标。

我刚刚意识到,只有值是整数,这种情况才有可能。如果value是varchar,那么在'sign之前总会有(sign,因此(SELECT否则其他任何东西都将像字符串一样起作用而不起作用。当字段是整数时,则'不需要它,这使得这种情况成为可能。但是整数应该始终用进行过滤,intval()因此这也不是问题。
JohnyFree 2015年

如果您先关闭'怎么办?那' AND (SELECT ...) '呢 顺便说一句,我不认为Zend不会引用这个……而且,如果您使用绑定,那么PDO将处理这个问题。只是永远不要使用这样的字符串连接:"sections.section= '$section'"
7ochem

在这种情况下,@ 7ochem必须使用?绑定参数。并且'将成为\'。但是,如果使用整数值,则不要绑定它,因为您可以使用intval()php函数将其清除,并且“某些东西将变为
0。– JohnyFree

Answers:


8

验证您的输入!

尽可能的好。

有关验证的一些建议:

  1. 检查通过GET参数获取的变量的长度。无需接受无休止的长字符串。

  2. 验证域名。您期望的域名使用哪种格式?它总是www.mydomain.tld吗?创建一个正则表达式来检查是否匹配或(更好)使用Zend_Validate_Hostname

    $validator = new Zend_Validate_Hostname();
    if ($validator->isValid($hostname)) {
        //hostname is valid - continue
    }
  3. 白名单:您知道要使用哪些域名吗?您可以创建一个允许的域列表并对其进行检查。放下其余的。

    $allowedDomains = array('www.domain1.tld','www.domain2.tld');
  4. 将域名和/或字符列入黑名单:如果希望使用域名,则无需接受除az,0-9和“。”以外的任何其他字符。(除非您使用的是特殊域名)。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.