Безопасность кучи памяти: сборка мусора строк - PullRequest
7 голосов
/ 15 ноября 2010

Недавно я проводил проверку кода безопасности для своей компании и использовал инструмент под названием Fortify360. Он идентифицирует многие проблемы с кодом и описывает проблемы. Интересная проблема, которую я поднял, что я не нашел никакой другой информации, заключается в следующем:

"Чувствительные данные (например, пароли), хранящиеся в памяти, могут быть утечки, если они хранятся в управляемом объекте String. Объекты String не закрепляются, поэтому сборщик мусора может перемещать эти объекты по своему желанию и оставлять несколько копий. в памяти. Эти объекты по умолчанию не зашифрованы, поэтому любой, кто может прочитать память процесса, сможет увидеть содержимое. Кроме того, если память процесса будет выгружена на диск, незашифрованное содержимое строки будет записано в файл подкачки. Наконец, поскольку объекты String являются неизменяемыми, удаление значения String из памяти может быть выполнено только сборщиком мусора CLR. Сборщик мусора не требуется для запуска, если в CLR недостаточно памяти, поэтому нет никакой гарантии относительно того, когда будет происходить сборка мусора. В случае сбоя приложения дамп памяти приложения может выявить конфиденциальные данные. "

Все это, как я понимаю, имеет смысл, и в моем исследовании проблемы это довольно стандартно.

Вопрос: как мне решить проблему? Предположим, что рассматриваемый класс или классы не могут наследоваться от iDisposable (очень большое приложение, и этот класс нужен еще долго после рассматриваемой строки). Есть ли альтернативный способ ручного управления памятью для удаления определенной строки без вызова сборщика мусора, GC.Collect () ??

Заранее признателен за помощь.

Alex

Ответы [ 2 ]

8 голосов
/ 15 ноября 2010

Если вы хотите избежать этого, вам нужно использовать System.SecureString , то есть IDisposable, для хранения конфиденциальных данных, удерживая их только в течение минимально необходимого времени.

Довольно иронично, что пример кода MSDN не Dispose экземпляр, ни явно, ни с инкапсуляцией using.

6 голосов
/ 15 ноября 2010

Честно говоря, решение этой "проблемы" принесет больше хлопот, чем стоит.

Нельзя предотвратить сохранение пользовательских паролей в строках при использовании таких технологий, как ASP.NET, если только вы не собираетесь шифровать строки на стороне клиента перед их отправкой, поскольку ASP.NET будет хранить их как строки в коллекциях форм и т.д.

И если вы пошли по пути JS-шифрования, обратите внимание, что любой потенциальный злоумышленник также сможет расшифровать строки, которые он восстановил из вашего приложения.

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

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

В итоге: если злоумышленник имеет право извлечь эти строки из памяти или подкачки, он также может делать вещи, которые намного хуже .

...