В PHP это хорошая практика для очистки / экранирования строки, чтобы использовать ее в сообщении об исключении?

Мне интересно, сообщения об исключениях обычно считаются безопасными для вывода? Или это нормально, если сообщение об исключении содержит небезопасную строку? (для XSS и т. д.) Какая санитария подойдет?

Например

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 ответ

Нет никаких строгих правил относительно того, как используются исключения, только правило, что вы не должны раскрывать внутреннюю работу.

Исключение 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()));
}
Другие вопросы по тегам