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 一些现成的搜索插件。
我有一个搜索引擎,它调用 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 一些现成的搜索插件。