未定义索引 - 安全风险与性能与代码膨胀
Undefined Index - Security Risk vs Performance vs Code Bloat
我正在合作一个项目,其中 REST API 基本上在开发模式下中断,因为它有更多包含错误报告策略。这是该项目中的典型行:
public function someAction() {
// Returns a map of params => values sent with HTTP req
$params = $this->getParams();
// This key may not exist --+
// |
// v
$someField = $params['someField'] ?: 'default value';
$someField = $this->sanitizeInput($someField);
// ...
}
因此,dev 模式下的 JSON 响应经常会出现 PHP: Notice: Undefined Index 警告,这会破坏JSON 输出字符串。
我的问题
- 假设变量已经初始化,特别是从 $_GET 或 $_POST 中提取它时,安全风险(如果有的话)到底是什么?
- 用
isset()
或 array_key_exists()
遍历并包装对某些假定数组键的每次访问是否值得?
- 我在整个应用程序的某些操作下引发 undef 索引警告的各个键周围添加了
isset()
,但代码现在看起来非常臃肿...
- 如果您的 JSON 交付 PHP 文件存在于单独的文件夹中,您应该为输入文件夹
- 理想情况下,您应该清理所有输入以防止各种攻击
参考 https://www.owasp.org/index.php/OWASP_Secure_Coding_Practices_-_Quick_Reference_Guide 以遵循最佳做法
忽略像这样的错误的问题正是您所发现的 - 调试变得非常痛苦,潜在的真正错误被忽略为 "normal behaviour"。
然而,与其他任何时候的编程一样,如果您发现自己一遍又一遍地编写相同的代码,您可能需要编写一个抽象。
在您的情况下,您可以向 class 添加一个额外的方法,以及 getParams
(大概只是 returns $_REQUEST
的内容),添加一个 getParam()
方法:
function getParam($key, $default=null)
{
return isset($_REQUEST[$key])? $_REQUEST[$key] : $default;
}
那么你的调用代码就变成了:
$someField = $this->getParam('someField', 'default value');
编辑您也可以将卫生调用添加到此方法中:
function getParam($key, $default=null)
{
return isset($_REQUEST[$key])? $this->sanitizeInput($_REQUEST[$key]) : $default;
}
进一步减少调用代码。现在您不仅拥有正确的无错误代码,而且还减少了三行调用代码:
$params = $this->getParams();
// This key may not exist --+
// |
// v
$someField = $params['someField'] ?: 'default value';
$someField = $this->sanitizeInput($someField);
致一:
$someField = $this->getParam('someField', 'default value');
我正在合作一个项目,其中 REST API 基本上在开发模式下中断,因为它有更多包含错误报告策略。这是该项目中的典型行:
public function someAction() {
// Returns a map of params => values sent with HTTP req
$params = $this->getParams();
// This key may not exist --+
// |
// v
$someField = $params['someField'] ?: 'default value';
$someField = $this->sanitizeInput($someField);
// ...
}
因此,dev 模式下的 JSON 响应经常会出现 PHP: Notice: Undefined Index 警告,这会破坏JSON 输出字符串。
我的问题
- 假设变量已经初始化,特别是从 $_GET 或 $_POST 中提取它时,安全风险(如果有的话)到底是什么?
- 用
isset()
或array_key_exists()
遍历并包装对某些假定数组键的每次访问是否值得? - 我在整个应用程序的某些操作下引发 undef 索引警告的各个键周围添加了
isset()
,但代码现在看起来非常臃肿...
- 如果您的 JSON 交付 PHP 文件存在于单独的文件夹中,您应该为输入文件夹
- 理想情况下,您应该清理所有输入以防止各种攻击
参考 https://www.owasp.org/index.php/OWASP_Secure_Coding_Practices_-_Quick_Reference_Guide 以遵循最佳做法
忽略像这样的错误的问题正是您所发现的 - 调试变得非常痛苦,潜在的真正错误被忽略为 "normal behaviour"。
然而,与其他任何时候的编程一样,如果您发现自己一遍又一遍地编写相同的代码,您可能需要编写一个抽象。
在您的情况下,您可以向 class 添加一个额外的方法,以及 getParams
(大概只是 returns $_REQUEST
的内容),添加一个 getParam()
方法:
function getParam($key, $default=null)
{
return isset($_REQUEST[$key])? $_REQUEST[$key] : $default;
}
那么你的调用代码就变成了:
$someField = $this->getParam('someField', 'default value');
编辑您也可以将卫生调用添加到此方法中:
function getParam($key, $default=null)
{
return isset($_REQUEST[$key])? $this->sanitizeInput($_REQUEST[$key]) : $default;
}
进一步减少调用代码。现在您不仅拥有正确的无错误代码,而且还减少了三行调用代码:
$params = $this->getParams();
// This key may not exist --+
// |
// v
$someField = $params['someField'] ?: 'default value';
$someField = $this->sanitizeInput($someField);
致一:
$someField = $this->getParam('someField', 'default value');