Ошибка ненадежной инициализации — при создании SQL-соединения

Я сделал следующее...

private static IDbConnectionProvider CreateSqlConnectionProvider(DbConfig dbConfig)
{
    return new QcDbConnectionProvider(() =>
        {
            SqlConnectionStringBuilder csBuilder = new SqlConnectionStringBuilder();

            if (!string.IsNullOrEmpty(dbConfig.DataSource)) 
                csBuilder.DataSource = dbConfig.DataSource;

            if (!string.IsNullOrEmpty(dbConfig.Database))
                csBuilder.InitialCatalog = dbConfig.Database;

            .
            .
            .
            .

            return new SqlConnection(csBuilder.ConnectionString);
        });
}

Клиент использует инструмент VERACODE для анализа кода, и VERACODE обнаружил ошибку «Ненадежная инициализация» на

return new SqlConnection(csBuilder.ConnectionString);

Кроме того, dbConfig инициализируется, как показано ниже...

DbConfig configDbConfig = new DbConfig
{
    Database = codeFile.ConfigurationDb,
    DataSource = codeFile.DataSource,
    IntegratedSecurity = sqlCredentials.UseWindowsAuthentication ? 1 : 0,
    UserId = sqlCredentials.UseWindowsAuthentication ? null : sqlCredentials.SqlUserName,
    ClearTextPassword = sqlCredentials.UseWindowsAuthentication ? null : sqlCredentials.SqlUserPassword
};

Что еще мне нужно сделать, чтобы исправить этот недостаток? Также согласно эта ссылка, я создаю строку подключения, используя SqlConnectionStringBuilder, что безопасно для создания строки подключения.

Заранее спасибо...


person NJMR    schedule 11.06.2015    source источник
comment
Откуда конусы codeFile?   -  person Adriano Repetti    schedule 15.06.2015
comment
Я не понял, что вы говорите...   -  person NJMR    schedule 15.06.2015
comment
почему бы не определить IntegratedSecurity как тип bool вместо int?   -  person Dreamweaver    schedule 15.06.2015
comment
@Dreamweaver: Дело принято...   -  person NJMR    schedule 15.06.2015
comment
@AdrianoRepetti: я читаю это из файла. if (TryReadCodeFile(configurationProfileFile, out codeFile, out errMessage, out errDescription)) { DbConfig configDbConfig = new DbConfig ....   -  person NJMR    schedule 15.06.2015


Ответы (2)


Описание проблемы Ненадежная инициализация:

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

В вашем случае вы читаете данные для dbConfig из файла:

 if (TryReadCodeFile(configurationProfileFile...)) {
     DbConfig configDbConfig = new DbConfig...
}

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

Из цитируемого абзаца: "...приложение позволяет внешний контроль над системными настройками или переменными, что может нарушить работу службы..." . В этом суть этой проблемы: если ваше приложение использует внешние данные без прямого контроля над ними, то его поведение можно изменить, изменив эти данные. Что это за внешние данные? Список полный, но не исчерпывающий:

  • Переменные среды (например, для определения пути к другому файлу или программе), поскольку пользователь может их изменить. Оригинальные файлы не трогаются, но вы читаете что-то еще.
  • Пути (для загрузки кода или данных), потому что пользователь может перенаправить на что-то еще (опять же исходные файлы не трогаются, но вы читаете что-то еще).
  • Поддержка файлов, поскольку пользователь может их изменить (в вашем случае, например, указать на другой сервер и/или каталог).
  • Файлы конфигурации, поскольку пользователь может их изменить (как указано выше).
  • Базы данных, потому что они могут быть доступны и другим пользователям и могут быть изменены (но они могут быть защищены).

Как злоумышленник может использовать это? Представьте, что каждый пользователь подключен к другому каталогу (в соответствии с их правилом в организации). Это нельзя изменить, и это настраивается во время установки. Если у них есть доступ к вашим файлам конфигурации, они могут изменить каталог на что-то другое. Они также могут изменить имя хоста БД на туннель, где они могут прослушивать данные (если у них есть физический доступ к чужой машине).

Также обратите внимание, что они также говорят "...при условии, что данные не могут быть подделаны, эти данные могут использоваться опасным образом". Это означает, что если, например, ваше приложение работает на веб-сервере и физический доступ защищен, вы можете считать эти данные безопасными.

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

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

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

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

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

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

person Adriano Repetti    schedule 15.06.2015

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

person Ashutosh B Bodake    schedule 08.09.2019