diff --git a/Kudu.Core/Helpers/KeyVaultReferenceHelper.cs b/Kudu.Core/Helpers/KeyVaultReferenceHelper.cs new file mode 100644 index 00000000..c524a946 --- /dev/null +++ b/Kudu.Core/Helpers/KeyVaultReferenceHelper.cs @@ -0,0 +1,99 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Linq; +using Newtonsoft.Json; + +namespace Kudu.Core.Helpers +{ + public static class KeyVaultReferenceHelper + { + private const string AppSettingPrefix = "APPSETTING_"; + private const string KeyVaultReferenceInfoEnvVar = "WEBSITE_KEYVAULT_REFERENCES"; + + /// Example dictionary: + /// { + /// "secret1": + /// { + /// { "rawReference", "@Microsoft.KeyVault(SecretUri=)" }, + /// { "status", "ValueNotFound" } + /// } + /// } + /// + private static Dictionary> KeyVaultReferencesInformation = GetKeyVaultReferencesInformation(); + + public static int NumKeyVaultReferences + { + get + { + return KeyVaultReferencesInformation.Count(); + } + } + + /// + /// Simple filter to hide secrets from KeyVault references. + /// + /// All variables for the site + /// Whether to hide KeyVault secrets + /// Filtered environment variables + public static IDictionary KeyVaultReferencesFilter(IDictionary variables, bool hideKeyVaultSecrets) + { + IDictionary filteredEnvironmentVariables = new Dictionary(); + foreach (var entry in variables.Keys) + { + filteredEnvironmentVariables.Add(entry, HideKeyVaultSecret(entry, variables[entry], hideKeyVaultSecrets)); + } + return filteredEnvironmentVariables; + } + + /// + /// Deserializes KeyVault References information in the form of a Dictionary> + /// + /// Serialized dictionary containing KeyVault reference information + public static Dictionary> GetKeyVaultReferencesInformation() + { + try + { + var serializedInformationBlob = System.Environment.GetEnvironmentVariable(KeyVaultReferenceInfoEnvVar); + if (serializedInformationBlob != null) + { + var result = JsonConvert.DeserializeObject>>(serializedInformationBlob); + if (result != null) + { + return result; + } + } + } + catch (Exception) + { + } + + return new Dictionary>(StringComparer.OrdinalIgnoreCase); + } + + /// + /// Hides a KeyVault secret if enabled, or just returns the original value if disabled + /// + /// Environment variable key + /// Environment variable original value + /// Whether to hide + /// Hidden value (or original) + public static object HideKeyVaultSecret(object key, object value, bool hideValue) + { + var keyString = (string)key; + if (hideValue && KeyVaultReferencesInformation.ContainsKey(keyString)) + { + try + { + return "[Hidden - " + KeyVaultReferencesInformation[keyString]["status"] + ": " + KeyVaultReferencesInformation[keyString]["rawReference"] + "]"; + } + catch (Exception) + { + return "[Hidden KeyVault secret]"; + } + } + + return value; + } + } +} diff --git a/Kudu.Services.Web/Pages/Env.cshtml b/Kudu.Services.Web/Pages/Env.cshtml index 7e23bb7e..bae05134 100644 --- a/Kudu.Services.Web/Pages/Env.cshtml +++ b/Kudu.Services.Web/Pages/Env.cshtml @@ -11,6 +11,18 @@

Index

+ + @{ + bool isHidden = String.IsNullOrEmpty(httpContextAccessor.HttpContext.Request.Query["hideSecrets"]) || ("true").Equals(httpContextAccessor.HttpContext.Request.Query["hideSecrets"]); // Hide by default + } + @if (Kudu.Core.Helpers.KeyVaultReferenceHelper.NumKeyVaultReferences > 0) + { +
+ +
+ }

AppSettings

+ @{ + var appSettingsInEnvironment = new Dictionary(_settingsManager.GetValues()); + var appSettingVariablesDict = Kudu.Core.Helpers.KeyVaultReferenceHelper.KeyVaultReferencesFilter(appSettingsInEnvironment, isHidden); + }
    @using System.Configuration; -@using System.Linq -@using Core.Infrastructure -@using Kudu.Contracts.Settings + @using System.Linq + @using Core.Infrastructure + @using Kudu.Contracts.Settings @using Microsoft.AspNetCore.Http @foreach (string name in System.Configuration.ConfigurationManager.AppSettings) { @@ -62,17 +78,18 @@ @name = @System.Configuration.ConfigurationManager.AppSettings[name] } - - @foreach (KeyValuePair kv in _settingsManager.GetValues()) - { - - if (kv.Value != null) - { -
  • @kv.Key = @kv.Value
  • - } - - } -
+ + @foreach (KeyValuePair kv in appSettingVariablesDict) + { + + if (kv.Value != null) + { +
  • @kv.Key = @kv.Value
  • + + } + + } +

    Connection Strings

      @@ -89,8 +106,12 @@

    Environment variables

    + @{ + IDictionary environmentVariables = Environment.GetEnvironmentVariables(); + var environmentVariablesDict = Kudu.Core.Helpers.KeyVaultReferenceHelper.KeyVaultReferencesFilter(environmentVariables, isHidden); + }
      - @foreach (DictionaryEntry entry in Environment.GetEnvironmentVariables().OfType().OrderBy(e => e.Key)) + @foreach (KeyValuePair entry in environmentVariablesDict.OfType>().OrderBy(e => e.Key)) {
    • @entry.Key = @entry.Value
    • } @@ -122,3 +143,23 @@
    *@
    + + diff --git a/Kudu.Services.Web/Pages/NewUI/Env.cshtml b/Kudu.Services.Web/Pages/NewUI/Env.cshtml index 7e23bb7e..df151d44 100644 --- a/Kudu.Services.Web/Pages/NewUI/Env.cshtml +++ b/Kudu.Services.Web/Pages/NewUI/Env.cshtml @@ -11,6 +11,18 @@

    Index

    + + @{ + bool isHidden = String.IsNullOrEmpty(httpContextAccessor.HttpContext.Request.Query["hideSecrets"]) || ("true").Equals(httpContextAccessor.HttpContext.Request.Query["hideSecrets"]); // Hide by default + } + @if (Kudu.Core.Helpers.KeyVaultReferenceHelper.NumKeyVaultReferences > 0) + { +
    + +
    + }

    AppSettings

    + @{ + var appSettingsInEnvironment = new Dictionary(_settingsManager.GetValues()); + var appSettingVariablesDict = Kudu.Core.Helpers.KeyVaultReferenceHelper.KeyVaultReferencesFilter(appSettingsInEnvironment, isHidden); + }
      @using System.Configuration; -@using System.Linq -@using Core.Infrastructure -@using Kudu.Contracts.Settings + @using System.Linq + @using Core.Infrastructure + @using Kudu.Contracts.Settings @using Microsoft.AspNetCore.Http @foreach (string name in System.Configuration.ConfigurationManager.AppSettings) { @@ -62,17 +78,18 @@ @name = @System.Configuration.ConfigurationManager.AppSettings[name] } - - @foreach (KeyValuePair kv in _settingsManager.GetValues()) + + @foreach (KeyValuePair kv in appSettingVariablesDict) { - - if (kv.Value != null) - { -
    • @kv.Key = @kv.Value
    • - } - + + if (kv.Value != null) + { +
    • @kv.Key = @kv.Value
    • + + } + } -
    +

    Connection Strings

      @@ -89,8 +106,12 @@

    Environment variables

    + @{ + IDictionary environmentVariables = Environment.GetEnvironmentVariables(); + var environmentVariablesDict = Kudu.Core.Helpers.KeyVaultReferenceHelper.KeyVaultReferencesFilter(environmentVariables, isHidden); + }
      - @foreach (DictionaryEntry entry in Environment.GetEnvironmentVariables().OfType().OrderBy(e => e.Key)) + @foreach (KeyValuePair entry in environmentVariablesDict.OfType>().OrderBy(e => e.Key)) {
    • @entry.Key = @entry.Value
    • } @@ -113,12 +134,32 @@
    @* -

    Server variables

    -
      - @foreach (string name in HttpContext.Connection.OfType().OrderBy(s => s)) - { -
    • @name=@HttpContext.Connection[name]
    • - } -
    - *@ +

    Server variables

    +
      + @foreach (string name in HttpContext.Connection.OfType().OrderBy(s => s)) + { +
    • @name=@HttpContext.Connection[name]
    • + } +
    + *@
    + +