Bonnes pratiques pour le déploiement des mots de passe et d’autres données sensibles sur ASP.NET et Azure App Service

par Rick Anderson

Ce tutoriel montre comment votre code peut stocker et accéder en toute sécurité aux informations sécurisées. Le point le plus important est que vous ne devez jamais stocker de mots de passe ou d’autres données sensibles dans le code source, et vous ne devez pas utiliser de secrets de production en mode développement et test.

L’exemple de code est une application console WebJob simple et une application MVC ASP.NET qui a besoin d’accéder à une base de données chaîne de connexion mot de passe, des clés sécurisées Twilio, Google et SendGrid.

Les paramètres locaux et PHP sont également mentionnés.

Utilisation des mots de passe dans l’environnement de développement

Les didacticiels montrent fréquemment des données sensibles dans le code source, avec une mise en garde que vous ne devez jamais stocker de données sensibles dans le code source. Par exemple, mon tutoriel ASP.NET application MVC 5 avec SMS et e-mail 2FA montre ce qui suit dans le fichier 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>

Le fichierweb.config étant du code source, ces secrets ne doivent jamais être stockés dans ce fichier. Heureusement, l’élément <appSettings> a un file attribut qui vous permet de spécifier un fichier externe qui contient des paramètres de configuration d’application sensibles. Vous pouvez déplacer tous vos secrets vers un fichier externe tant que le fichier externe n’est pas archivé dans votre arborescence source. Par exemple, dans le balisage suivant, le fichier AppSettingsSecrets.config contient tous les secrets d’application :

</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>

Le balisage du fichier externe (AppSettingsSecrets.config dans cet exemple) est le même que celui du fichier 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>

Le runtime ASP.NET fusionne le contenu du fichier externe avec l’élément de balisage dans <appSettings> . Le runtime ignore l’attribut de fichier si le fichier spécifié est introuvable.

Avertissement

Sécurité : n’ajoutez pas vos secrets .config fichier à votre projet ni ne l’case activée dans le contrôle de code source. Par défaut, Visual Studio définit sur Build ActionContent, ce qui signifie que le fichier est déployé. Pour plus d’informations, consultez Pourquoi tous les fichiers de mon dossier de projet ne sont-ils pas déployés ? Bien que vous puissiez utiliser n’importe quelle extension pour les secrets .config fichier, il est préférable de le conserver .config, car les fichiers de configuration ne sont pas pris en charge par IIS. Notez également que le fichier AppSettingsSecrets.config se trouve à deux niveaux de répertoire à partir du fichier web.config . Il est donc complètement en dehors du répertoire de la solution. En déplaçant le fichier hors du répertoire de solution, « git add * » ne l’ajoutera pas à votre dépôt.

Utilisation des chaînes de connexion dans l’environnement de développement

Visual Studio crée de nouveaux projets ASP.NET qui utilisent LocalDB. LocalDB a été créé spécifiquement pour l’environnement de développement. Il ne nécessite pas de mot de passe. Par conséquent, vous n’avez pas besoin de faire quoi que ce soit pour empêcher l’enregistrement des secrets dans votre code source. Certaines équipes de développement utilisent les versions complètes de SQL Server (ou d’autres SGBD) qui nécessitent un mot de passe.

Vous pouvez utiliser l’attribut configSource pour remplacer l’intégralité <connectionStrings> du balisage. Contrairement à l’attribut <appSettings>file qui fusionne le balisage, l’attribut configSource remplace le balisage. Le balisage suivant montre l’attribut configSource dans le fichier web.config :

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

Notes

Si vous utilisez l’attribut configSource comme indiqué ci-dessus pour déplacer vos chaînes de connexion vers un fichier externe et que Visual Studio crée un site web, il ne sera pas en mesure de détecter que vous utilisez une base de données et vous n’aurez pas la possibilité de configurer la base de données lorsque vous publiez sur Azure à partir de Visual Studio. Si vous utilisez l’attribut configSource , vous pouvez utiliser PowerShell pour créer et déployer votre site web et votre base de données, ou vous pouvez créer le site web et la base de données dans le portail avant de publier.

Avertissement

Sécurité : contrairement au fichier AppSettingsSecrets.config, le fichier de chaînes de connexion externe doit se trouver dans le même répertoire que le fichier web.config racine. Vous devez donc prendre des précautions pour vous assurer de ne pas le case activée dans votre référentiel source.

Notes

Avertissement de sécurité sur le fichier secret : Une bonne pratique consiste à ne pas utiliser de secrets de production dans le test et le développement. L’utilisation de mots de passe de production dans le test ou le développement permet de divulguer ces secrets.

Applications console WebJobs

Le fichier app.config utilisé par une application console ne prend pas en charge les chemins relatifs, mais il prend en charge les chemins d’accès absolus. Vous pouvez utiliser un chemin d’accès absolu pour déplacer vos secrets hors de votre répertoire de projet. Le balisage suivant montre les secrets dans le fichier C:\secrets\AppSettingsSecrets.config et les données non sensibles dans le fichier 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>

Déploiement de secrets sur Azure

Lorsque vous déployez votre application web sur Azure, le fichier AppSettingsSecrets.config n’est pas déployé (c’est ce que vous voulez). Vous pouvez accéder au portail de gestion Azure et les définir manuellement pour ce faire :

  1. Accédez à https://portal.azure.com, puis connectez-vous avec vos informations d’identification Azure.
  2. Cliquez sur Parcourir > Web Apps, puis sur le nom de votre application web.
  3. Cliquez sur Tous les paramètres > Paramètres de l’application.

Les paramètres d’application et les valeurs chaîne de connexion remplacent les mêmes paramètres dans le fichier web.config. Dans notre exemple, nous n’avons pas déployé ces paramètres sur Azure, mais si ces clés se trouvaient dans le fichier web.config , les paramètres affichés sur le portail seraient prioritaires.

Il est recommandé de suivre un workflow DevOps et d’utiliser Azure PowerShell (ou une autre infrastructure telle que Chef ou Puppet) pour automatiser la définition de ces valeurs dans Azure. Le script PowerShell suivant utilise Export-CliXml pour exporter les secrets chiffrés sur le disque :

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

Dans le script ci-dessus, « Name » est le nom de la clé secrète, par exemple « FB_AppSecret » ou « TwitterSecret ». Vous pouvez afficher le fichier .credential " créé par le script dans votre navigateur. L’extrait de code ci-dessous teste chacun des fichiers d’informations d’identification et définit les secrets de l’application web nommée :

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

Avertissement

Sécurité : n’incluez pas de mots de passe ou d’autres secrets dans le script PowerShell, ce qui va à l’inverse de l’objectif de l’utilisation d’un script PowerShell pour déployer des données sensibles. L’applet de commande Get-Credential fournit un mécanisme sécurisé pour obtenir un mot de passe. L’utilisation d’une invite d’interface utilisateur peut empêcher la fuite d’un mot de passe.

Déploiement de chaînes de connexion de base de données

Les chaînes de connexion de base de données sont gérées de la même manière que les paramètres d’application. Si vous déployez votre application web à partir de Visual Studio, le chaîne de connexion sera configuré pour vous. Vous pouvez le vérifier dans le portail. La méthode recommandée pour définir le chaîne de connexion consiste à utiliser PowerShell.

Remarques pour PHP

Étant donné que les paires clé-valeur pour les paramètres d’application et les chaînes de connexion sont stockées dans des variables d’environnement sur Azure App Service, les développeurs qui utilisent n’importe quelle infrastructure d’application web (comme PHP) peuvent facilement récupérer ces valeurs. Consultez le billet de blog de Stefan Schackow sur Windows Azure Web Sites : How Application Strings and Connection Strings Work qui montre un extrait de code PHP pour lire les paramètres d’application et les chaînes de connexion.

Remarques pour les serveurs locaux

Si vous déployez sur des serveurs web locaux, vous pouvez sécuriser les secrets en chiffrant les sections de configuration des fichiers de configuration. Vous pouvez également utiliser la même approche que celle recommandée pour les sites web Azure : conserver les paramètres de développement dans les fichiers de configuration et utiliser des valeurs de variable d’environnement pour les paramètres de production. Dans ce cas, toutefois, vous devez écrire du code d’application pour les fonctionnalités automatiques dans les sites Web Azure : récupérez les paramètres des variables d’environnement et utilisez ces valeurs à la place des paramètres du fichier de configuration, ou utilisez les paramètres du fichier de configuration lorsque des variables d’environnement sont introuvables.

Ressources supplémentaires

Consultez Sites web Windows Azure de Stefan Schackow : fonctionnement des chaînes d’application et des chaînes de connexion

Un merci spécial à Barry Dorrans ( @blowdart ) et Carlos Farre pour sa révision.