我想知道,通常认为输出安全的异常消息是什么?或者如果异常消息包含不安全的字符串,它可以吗? (适用于XSS等) 什么样的消毒适合?
E.g。
function lookupOrExplode(array $array, $key) {
if (!array_key_exists($str, $array)) {
// @todo Sanitize $key before using it in the exception message?
throw new \InvalidArgumentException("Key '$key' not found.");
}
}
我个人认为在catch()块中,来自异常的消息必须被视为可能不安全,因为它可能来自任何地方。但throw()语句仍然可以尝试使消息有点理智。
但也许有人可以提供更详细的建议,例如:基于常见php框架的标准...
注意:我们不要争论InvalidArgumentException是否是在这种情况下使用的正确或合适的异常类。这是一个快速而肮脏的例子,重点应放在字符串处理上。
答案 0 :(得分:2)
对于如何使用例外没有严格的规定,只有不应该公开内部工作的规则。
异常InvalidArgumentException
在语义上或安全上都不可能被用户读取,无论消息包含什么。
在下面的示例中,自定义异常HTTPException
将意味着"将输出到客户端"。该消息将包含与应用程序,浏览器和用户相关的信息。
处理界面(例如用户界面和浏览器)的类和函数应该为用户错误抛出HTTP异常,或者为致命错误抛出常规异常。
/**
* Class HTTPException
*
* new HTTPException($message, $code)
* new Exception($message, $code)
*
* Arguments are compatible:
* $message, error message
* $code, http error code
*/
class HTTPException extends Exception
{
}
// Further up the stack
try {
// ...
} catch (HTTPException $exception) {
// Catch HTTP exception
// Respond directly to user with message
// or create error screen from template
} catch (Exception $exception) {
// Catch any exception.
// Return 500 error or any other error.
}
我要指出的另一件事是InvalidArgumentException
更适合无效的参数,即格式无效,类型无效等。
PHP缺乏内置的例外,但您可以自己创建它们。构建标准异常的一个很好的来源是.NET
https://mikevallotton.wordpress.com/2009/07/08/net-exceptions-all-of-them/
对于我将使用的函数KeyNotFoundException
,因为它准确描述了问题所在,并且只要值是正确的类型和格式,它就不是无效的。
所以新代码可能如下所示:
class NotFoundHttpException extends HttpException
{
public function __construct($message, Exception $previous = null)
{
parent::__construct($message, 404, $previous);
}
}
try {
$v = lookupOrExplode(/* args */);
} catch (KeyNotFoundException $exception) {
throw new NotFoundHttpException(
sprintf('Key "%s" not found in lookup table.',
$exception->getKey()));
}