Нужно ли оборачивать каждое исключение на верхнем уровне? - PullRequest
3 голосов
/ 20 февраля 2012

Сегодня кто-то сказал мне, что мы всегда должны переносить каждое исключение на верхний уровень фреймворка.Причина в том, что исходное исключение может содержать конфиденциальную информацию в трассировке стека или сообщении, особенно в трассировке стека.

Я не знаю, есть ли какие-либо правила / принципы / шаблоны?

Ответы [ 4 ]

15 голосов
/ 20 февраля 2012

Сегодня кто-то сказал мне, что мы всегда должны переносить каждое исключение на верхний уровень фреймворка.

«Всегда» кажется немного большим.

Как и любое другое дизайнерское решение, вы должны учитывать затраты и выгоды.

Поскольку исходное исключение может содержать конфиденциальную информацию в трассировке стека или в сообщении, особенно в трассировке стека. * * 1010

В самом деле, исключение может содержать конфиденциальную информацию, а злоумышленник может использовать трассировку стека.

Существуют ли какие-либо правила / принципы / шаблоны?

Да. Перед тем, как сделать что-нибудь , особенно перед тем, как внести изменения в дизайн или код, создайте модель угрозы . Вы задаете вопрос security , и поэтому вам абсолютно необходимо понять угроз , прежде чем вы сможете разработать хорошую стратегию для устранения уязвимостей.

Основными вопросами, на которые отвечает ваша модель угрозы, должно быть: " Каковы границы доверия моего приложения? Когда и как данные пересекают границу? Какие уязвимости делает это разоблачение? На какие угрозы может подойти злоумышленник в результате?"

Если вы точно не понимаете, что такое границы доверия, уязвимости, угрозы и злоумышленники, узнайте, что означают эти слова за до , и вы попытаетесь спроектировать систему безопасности для смягчения уязвимостей для угроз. «Написание безопасного кода 2» - хорошее место для начала. (Глава 5 моей книги по безопасности кода содержит несколько полезных советов по устранению уязвимостей исключений, но она давно вышла из печати. ​​Возможно, я выложу ее в блог на днях.)

Данные могут пересекать границу доверия в любом направлении; ненадежный клиент может отправлять искаженные данные на ваш сервер, а ваш сервер может отправлять конфиденциальные конфиденциальные данные ненадежному клиенту.

Особый аспект модели угроз, который конкретно касается вашего вопроса, - это данные в форме исключений. Я не шучу, до того, как мы выпустили .NET 1.0, вы могли бы получить платформу для исключения, чей текст был что-то вроде «У вас нет разрешения определять имя каталога C: \ foo». (Отлично. Спасибо, что сообщили мне об этом. Сейчас я не буду использовать эту информацию для атаки на пользователя.)

Очевидно, что это было исправлено задолго до нашей отправки, но люди делают моральный эквивалент этого каждый день. Если у вас есть данные, пересекающие границу доверия, вы должны предположить, что враждебный пользователь на ненадежной стороне попытается вызвать исключения на доверенной стороне и постарается узнать как можно больше об этой системе из этих исключений. Не упрощайте работу злоумышленника.

Вы спросили, следует ли переносить все исключения. Может быть. Если на самом деле у вас есть проблема - если исключение, содержащее конфиденциальные данные, может пересечь границу доверия, то, возможно, правильное решение - обернуть исключение Но, может быть, этого недостаточно достаточно . Возможно, вам вообще не нужно выбрасывать исключение через границу, даже если исключение можно очистить. Может быть, правильнее всего сделать следующее: полностью предупредить об этом и сказать «эй, мы получили неожиданное исключение, вызванное неверными данными от потенциально враждебной третьей стороны, поэтому давайте (1) забаним их IP или (2) перенаправим их на сервер honeypot, или (3) предупредить отдел безопасности, или (4) что-то еще. " Правильное решение зависит от угрозы , о которой вы еще не заявили.

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

0 голосов
/ 20 февраля 2012

Отображение трассировки стека для пользователя в нормальных условиях не лучшая идея.Я использую для отладки и разработки константу DEBUG, установленную в «true», и в нормальных условиях в «false», посмотрите на этот пример PHP

DEFINE("DEBUG" true);

function soap_error($soapFault)
{
if (DEBUG)
    {
        // full message with stack including sensitive info
        echo '<p class="error">SOAP error:</p><br />';
        echo '<p>'.$soapFault.'</p><br />';
        echo '<hr />';
    }
    else
    {
        // only error message           
        echo '<p class="error">SOAP error:</p><br />';
        echo '<p>'.$soapFault->getMessage().'</p><br />';
        echo '<hr />';
    }
}

. Вы также можете использовать файлы журналов для сохранения полных стеков ошибок.

В C # /. NET это проще, потому что у вас есть конфигурации сборки в Visual Studio, и вы можете переключаться между ними и использовать что-то вроде этого:

public static void myerrorhandler(Exeption e) 
 {
 #if (DEBUG) // you have DEBUG and RELEASE configurations by default
 yourErrorMessageFunction("This is error message and stack " + e.toString()); 
 #else
 yourErrorMessageFunction("This is only message" + e.Message());
 #endif
 }

Visual Studio добавляет и контролируетКонстанта DEBUG (она установлена ​​в «Конфигурации сборки», вы можете настроить ее там).

0 голосов
/ 20 февраля 2012

Эрик Липперт написал отличный блог о том, какие исключения должны быть пойманы и где.

Исключения Vexing

Он не дает прямого ответа на ваш вопрос, но дает хорошее представление об общей обработке исключений.

0 голосов
/ 20 февраля 2012

Да, есть правило: это глупо.

Нам нужно знать больше деталей, но в конце:

  • Вы можете и должны иметь обработчик верхнего уровня для исключений. Это не в вашей структуре (т.е. обертывание верхнего уровня), а привязано к домену приложения (необработанное исключение). Это позволяет вам показывать сообщение об ошибке и записывать логи и т. Д.

  • В конце вы должны распространять как можно больше информации. Правило гласит: «лови то, с чем ты можешь справиться, распространяй, что не можешь».

  • Теперь это смешно. «конфиденциальная информация» - это «информация, полезная и нужная для отладки». В высших стандартах говорится: «Обернуть исключение = оригинал переходит во внутреннее свойство исключения».

Фреймворк не должен предоставлять пользователю конфиденциальную информацию, но это зависит от приложения (то есть: пользовательская страница ошибок, оконные окна и т. Д .: обработчик последней инстанции, не показывающий пользователю слишком много подробностей, потому что пользователю все равно все равно).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...