CakePHP3:检查模型是否存在

时间:2017-07-16 13:27:20

标签: cakephp model cakephp-3.0

我有一个搜索引擎,它调用Cakephp动作并接收引擎应该搜索的模型,例如。 “项目”。该变量称为$data_type;

现在我用它来检查模型是否存在:

// Check if Table really exists
    if(!TableRegistry::get($data_type)){

        // Send error response to view
        $response = [
            'success' => false,
            'error' => 'Data type does not exist'
        ];
        $this->set('response', $response);
        return;
    }

我不确定我是否正确或最安全地检查模型是否存在,因为我不知道TableRegistry::get()函数是否容易受到幕后SQL注入的影响。

我还发现在get()函数中输入一个空字符串不需要在false结果中???我能实施哪种安全解决方案可以解决我的问题吗?

1 个答案:

答案 0 :(得分:1)

TableRegistry::get()与用户输入一起使用是不安全的

首先要做的事情。通过TableRegistry::get()注入危险的SQL可能相当复杂,但并非不可能,因为在创建auto / generic-table实例的情况下,第一个参数中传递的别名将用作数据库表名。然而,模式查找很可能在其他任何事情之前失败,名称也会受到变形,特别是下划线和小写变形,因此注入尝试如

Foo; DELETE * FROM Bar;

最终会成为:

foo;d_e_l_e_t_e*f_r_o_m_bar;

这会破坏因为它是无效的SQL,但它不会造成进一步的伤害。但最重要的是 TableRegistry::get()不能被视为对用户输入使用安全!

返回实例的类表示表类'存在

TableRegistry::get()查找并实例化给定别名的可能现有表类,如果失败,它将创建一个所谓的auto / generic-table,它是\Cake\ORM\Table的实例,而不是一个具体子类的实例。

因此,您可以检查\Cake\ORM\Table的返回值,以确定您是否检索了实际现有表类的实例:

$table = TableRegistry::get($data_type);
if (get_class($table) === \Cake\ORM\Table::class) {
    // not an existing table class
    // ...
}

使用白名单

话虽如此,除非您正在开发明确需要能够访问所有表的某种管理工具,但正确的做法是使用某种白名单,因为用户可以任意查找任何表他们想要的表可能存在安全风险

$whitelist = [
    'Projects',
    '...'
];

if (in_array($data_type, $whitelist, true) !== true) {
    // not in the whitelist, access prohibited
    // ...
}

理想情况下,您可以更进一步,对可以查找的列应用类似的限制。

您可能需要查看 https://github.com/FriendsOfCake/awesome-cakephp#search 以查找一些现成的搜索插件。