Безопасное хранение паролей

#std740

Область применения: управляемое приложение, мобильное приложение, обычное приложение.

1. При разработке подсистем, взаимодействующих с различными внешними ресурсами (электронной почтой, веб-сервисами, FTP-ресурсами и т.п.) возникает необходимость запрашивать и передавать данные аутентификации к этим ресурсам: логин и пароль.

2. Для сведения к минимуму возможности перехвата пароля злоумышленниками не следует хранить пароли и другую конфиденциальную информацию в информационной базе. При этом минимальный уровень защищенности – в файловых информационных базах, в которых файл базы может быть скопирован целиком любым пользователем информационной базы. В клиент-серверной информационной базе доступ к базе данных, как правило, имеется только у администраторов СУБД.

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

3. В ряде случаев такая схема работы доставляет объективные неудобства или принципиально невозможна:

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

3.1. При этом не следует хранить пароли и другую конфиденциальную информацию в реквизитах тех же объектов метаданных, с которыми ведется повседневная работа. Для хранения такой информации следует использовать отдельный объект метаданных (например, регистр сведений), организовав к нему безопасный доступ на уровне системы прав доступа 1С:Предприятия.

3.2. При использовании Библиотеки стандартных подсистем (БСП) следует использовать безопасное хранилище паролей, которое решает ряд задач:

Для работы с безопасным хранилищем паролей предназначены процедуры и функции общего модуля ОбщегоНазначения: ЗаписатьДанныеВБезопасноеХранилищеПрочитатьДанныеИзБезопасногоХранилища и УдалитьДанныеИзБезопасногоХранилища. Подробнее см. комментарии к этим функциям в БСП и раздел «3.4. Базовая функциональность - Использование при разработке конфигурации - Безопасное хранилище паролей» документации БСП.

3.3. Не следует хранить пароли в реквизитах формы, их следует извлекать только на стороне сервера и непосредственно перед их использованием. В противном случае, при открытии формы с маскированным вводом (или просмотром) пароля, пароль передается с  сервера на клиент в открытом виде, что делает возможным его перехват. Установка привилегированного режима производится непосредственно перед вызовом функций, а не внутри них, что бы исключить получение или запись любых паролей в сеансе с любыми правами. Безопасность вызова должен обеспечивать вызывающий код, который обращается к конкретным паролям.

Для маскировки пароля на форме в обработчике событии формы ПриСозданииНаСервере необходимо разместить следующий код:

 УстановитьПривилегированныйРежим(Истина);
 Пароли = ОбщегоНазначения.ПрочитатьДанныеИзБезопасногоХранилища(Объект.Ссылка, "Пароль, ПарольSMTP"); // Пароль, ПарольSMTP – ключи соответствия данных в безопасном хранилище
 УстановитьПривилегированныйРежим(Ложь);

 Пароль = ?(ЗначениеЗаполнено(Пароли.Пароль), ЭтотОбъект.УникальныйИдентификатор, "");
 ПарольSMTP = ?(ЗначениеЗаполнено(Пароли.ПарольSMTP), ЭтотОбъект.УникальныйИдентификатор, "");

В обработчике события формы ПриЗаписиНаСервере:

 Если ПарольИзменен Тогда
  УстановитьПривилегированныйРежим(Истина);
  ОбщегоНазначения.ЗаписатьДанныеВБезопасноеХранилище(ТекущийОбъект.Ссылка, Пароль);
  УстановитьПривилегированныйРежим(Ложь);
  Пароль = ?(ЗначениеЗаполнено(Пароль), ЭтотОбъект.УникальныйИдентификатор, "");
 КонецЕсли;
 
 Если ПарольSMTPИзменен Тогда
  УстановитьПривилегированныйРежим(Истина);
  ОбщегоНазначения.ЗаписатьДанныеВБезопасноеХранилище(ТекущийОбъект.Ссылка, ПарольSMTP, "ПарольSMTP");
  УстановитьПривилегированныйРежим(Ложь);
  ПарольSMTP = ?(ЗначениеЗаполнено(ПарольSMTP), ЭтотОбъект.УникальныйИдентификатор, "");
 КонецЕсли;

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