Поделиться через


Рекомендации по развертыванию паролей и других конфиденциальных данных в ASP.NET и службу приложений Azure

Рик Андерсон

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

Пример кода — это простое консольное приложение веб-задания и приложение ASP.NET MVC, которое требует доступа к базе данных строка подключения паролем, Twilio, Google и SendGrid secure key.

Также упоминаются локальные параметры и PHP.

Работа с паролями в среде разработки

Руководства часто показывают конфиденциальные данные в исходном коде, надеюсь, с предупреждением о том, что конфиденциальные данные никогда не следует хранить в исходном коде. Например, мое приложение ASP.NET MVC 5 с SMS и электронной почтой 2FA показывает следующее в файле web.config :

</connectionStrings>
   <appSettings>
      <add key="webpages:Version" value="3.0.0.0" />
      <!-- Markup removed for clarity. -->
      
      <!-- SendGrid-->
      <add key="mailAccount" value="account" />
      <add key="mailPassword" value="my password" />
      <!-- Twilio-->
      <add key="TwilioSid" value="My SID" />
      <add key="TwilioToken" value="My Token" />
      <add key="TwilioFromPhone" value="+12065551234" />

      <add key="GoogClientID" value="1234.apps.googleusercontent.com" />
      <add key="GoogClientSecret" value="My GCS" />
   </appSettings>
 <system.web>

Файл web.config является исходным кодом, поэтому эти секреты никогда не должны храниться в этом файле. К счастью, <appSettings> элемент имеет file атрибут, позволяющий указать внешний файл, содержащий конфиденциальные параметры конфигурации приложения. Все секреты можно переместить во внешний файл, пока внешний файл не установлен в исходное дерево. Например, в следующей разметке файл AppSettingsSecrets.config содержит все секреты приложения:

</connectionStrings>
   <appSettings file="..\..\AppSettingsSecrets.config">      
      <add key="webpages:Version" value="3.0.0.0" />
      <add key="webpages:Enabled" value="false" />
      <add key="ClientValidationEnabled" value="true" />
      <add key="UnobtrusiveJavaScriptEnabled" value="true" />      
   </appSettings>
  <system.web>

Разметка во внешнем файле (AppSettingsSecrets.config в этом примере) является той же разметкой, что и в файле конфигурации web.config:

<appSettings>   
   <!-- SendGrid-->
   <add key="mailAccount" value="My mail account." />
   <add key="mailPassword" value="My mail password." />
   <!-- Twilio-->
   <add key="TwilioSid" value="My Twilio SID." />
   <add key="TwilioToken" value="My Twilio Token." />
   <add key="TwilioFromPhone" value="+12065551234" />

   <add key="GoogClientID" value="1.apps.googleusercontent.com" />
   <add key="GoogClientSecret" value="My Google client secret." />
</appSettings>

Среда выполнения ASP.NET объединяет содержимое внешнего файла с разметкой в <элементе appSettings> . Если указанный файл не удается найти, среда выполнения игнорирует атрибут файла.

Предупреждение

Безопасность. Не добавляйте в проект файл конфигурации секретов или не проверяйте его в системе управления версиями. По умолчанию Visual Studio задает значение Build Action Content, что означает, что файл развертывается. Дополнительные сведения см. в статье "Почему не все файлы в папке проекта развертываются?" Несмотря на то что для файла конфигурации секретов можно использовать любое расширение, рекомендуется сохранить его конфигурацию, так как файлы конфигурации не обслуживаются службами IIS. Обратите внимание, что файл AppSettingsSecrets.config составляет два уровня каталогов из файла web.config , поэтому он полностью выходит из каталога решения. Переместив файл из каталога решения, "git add *" не добавит его в репозиторий.

Работа с строка подключения в среде разработки

Visual Studio создает новые проекты ASP.NET, использующие LocalDB. LocalDB был создан специально для среды разработки. Это не требует пароля, поэтому вам не нужно ничего делать, чтобы предотвратить проверку секретов в исходном коде. В некоторых командах разработчиков используются полные версии SQL Server (или других СУБД), для которых требуется пароль.

Атрибут можно использовать configSource для замены всей <connectionStrings> разметки. В отличие от атрибута <appSettings> file , который объединяет разметку, configSource атрибут заменяет разметку. В следующей разметке показан configSource атрибут в файле web.config:

<connectionStrings configSource="ConnectionStrings.config">
</connectionStrings>

Примечание.

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

Предупреждение

Безопасность. В отличие от файла AppSettingsSecrets.config, внешний файл строка подключения s должен находиться в том же каталоге, что и корневой файл web.config, поэтому необходимо принять меры предосторожности, чтобы убедиться, что вы не проверьте его в исходном репозитории.

Примечание.

Предупреждение системы безопасности в файле секретов. Рекомендуется не использовать рабочие секреты в тестировании и разработке. Использование рабочих паролей в тестовых или разработках утечки этих секретов.

Консольные приложения веб-заданий

Файл app.config , используемый консольным приложением, не поддерживает относительные пути, но поддерживает абсолютные пути. Вы можете использовать абсолютный путь для перемещения секретов из каталога проекта. В следующей разметке показаны секреты в файле C:\secret\AppSettingsSecrets.config и не конфиденциальные данные в файле app.config .

<configuration>
  <appSettings file="C:\secrets\AppSettingsSecrets.config">
    <add key="TwitterMaxThreads" value="24" />
    <add key="StackOverflowMaxThreads" value="24" />
    <add key="MaxDaysForPurge" value="30" />
  </appSettings>
</configuration>

Развертывание секретов в Azure

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

  1. https://portal.azure.comПерейдите в систему и войдите с помощью учетных данных Azure.
  2. Нажмите кнопку "Обзор > веб-приложения", а затем щелкните имя веб-приложения.
  3. Нажмите кнопку "Все параметры >приложения".

Параметры приложения и строка подключения значения переопределяют те же параметры в файле web.config. В нашем примере мы не развернули эти параметры в Azure, но если эти ключи были в файле web.config , параметры, отображаемые на портале, будут иметь приоритет.

Рекомендуется следовать рабочему процессу DevOps и использовать Azure PowerShell (или другую платформу, например Chef или Puppet), чтобы автоматизировать настройку этих значений в Azure. Следующий сценарий PowerShell использует Export-CliXml для экспорта зашифрованных секретов на диск:

param(
  [Parameter(Mandatory=$true)] 
  [String]$Name,
  [Parameter(Mandatory=$true)]
  [String]$Password)

$credPath = $PSScriptRoot + '\' + $Name + ".credential"
$PWord = ConvertTo-SecureString –String $Password –AsPlainText -Force 
$Credential = New-Object –TypeName `
System.Management.Automation.PSCredential –ArgumentList $Name, $PWord
$Credential | Export-CliXml $credPath

В приведенном выше скрипте "Имя" — это имя секретного ключа, например ""FB_AppSecret" или "TwitterSecret". Файл ".credential", созданный скриптом в браузере, можно просмотреть. Приведенный ниже фрагмент проверяет каждый из файлов учетных данных и задает секреты для именованного веб-приложения:

Function GetPW_fromCredFile { Param( [String]$CredFile )
  $Credential = GetCredsFromFile $CredFile
  $PW = $Credential.GetNetworkCredential().Password  
  # $user just for debugging.
  $user = $Credential.GetNetworkCredential().username 
  Return $PW
}	
$AppSettings = @{	
  "FB_AppSecret"     = GetPW_fromCredFile "FB_AppSecret.credential";
  "GoogClientSecret" = GetPW_fromCredFile "GoogClientSecret.credential";
  "TwitterSecret"    = GetPW_fromCredFile "TwitterSecret.credential";
}
Set-AzureWebsite -Name $WebSiteName -AppSettings $AppSettings

Предупреждение

Безопасность. Не включайте пароли или другие секреты в скрипт PowerShell, что позволяет победить цель использования скрипта PowerShell для развертывания конфиденциальных данных. Командлет Get-Credential предоставляет безопасный механизм для получения пароля. Запрос пользовательского интерфейса может предотвратить утечку пароля.

Развертывание строка подключения базы данных

Строка подключения базы данных обрабатываются аналогично параметрам приложения. При развертывании веб-приложения из Visual Studio строка подключения будет настроено для вас. Это можно проверить на портале. Рекомендуется задать строка подключения с помощью PowerShell.

Примечания для PHP

Так как пары "ключ-значение" для параметров приложения и строка подключения хранятся в переменных среды в службе приложение Azure, разработчики, использующие любые платформы веб-приложений (например, PHP), могут легко получить эти значения. См. статью о веб-сайтах Windows Azure в Стефане Schackow: как строки приложения и строки подключения работают в блоге, в котором показан фрагмент PHP для чтения параметров приложения и строка подключения.

Заметки о локальных серверах

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

Дополнительные ресурсы

См. веб-сайты Windows Azure в Стефане Шокове : как работают строки приложения и строки подключения

Особое спасибо Барри Дорранс ( @blowdart ) и Карлос Фарре за просмотр.