CakePHP3:检查模型是否存在

CakePHP3: Check if model exists

我有一个搜索引擎,它调用 Cakephp 操作并接收引擎应该搜索的模型,例如。 "Projects"。该变量称为 $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() 函数中输入空字符串不需要得到错误的结果???有没有我可以实施的安全解决方案来解决我的问题?

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

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

Foo; DELETE * FROM Bar;

最终会变成:

foo;d_e_l_e_t_e*f_r_o_m_bar;

这会破坏一些东西,因为它是无效的 SQL,但它不会造成进一步的伤害。然而,最重要的是 TableRegistry::get() 不能被视为可以安全地与用户输入一起使用!

returned 实例的 class 表示 table class' 存在

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

因此,您可以对照 \Cake\ORM\Table 检查 return 值,以确定您是否检索了实际存在的实例 table class:

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

使用白名单

也就是说,除非您正在开发某种明确需要能够访问所有 table 的管理工具,否则正确的做法是使用某种白名单,因为让用户任意查找他们想要的任何 table可能存在安全风险:

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

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

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

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