在PHP中,清理/转义字符串以在异常消息中使用它是一种好习惯吗?

时间:2016-01-11 10:44:08

标签: php exception sanitization

我想知道,通常认为输出安全的异常消息是什么?或者如果异常消息包含不安全的字符串,它可以吗? (适用于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是否是在这种情况下使用的正确或合适的异常类。这是一个快速而肮脏的例子,重点应放在字符串处理上。

1 个答案:

答案 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()));
}