From 13e14e8596582df90999553b7c23b01378c9c60e Mon Sep 17 00:00:00 2001 From: Jacob Viau Date: Mon, 1 Jul 2024 17:35:12 -0700 Subject: [PATCH] Address test secrets being flagged --- .../Management/InstanceControllerTests.cs | 19 ++++---- .../KubernetesPodControllerTests.cs | 9 ++-- .../Management/MeshServiceClientTests.cs | 9 +--- .../TestHelpers.Constants.cs | 46 +++++++++++++++++++ .../TestHelpers.cs | 18 -------- .../WebJobs.Script.Tests.Shared.projitems | 1 + .../Security/SecretManagerTests.cs | 9 ++-- .../StartupContextProviderTests.cs | 5 +- 8 files changed, 64 insertions(+), 52 deletions(-) create mode 100644 test/WebJobs.Script.Tests.Shared/TestHelpers.Constants.cs diff --git a/test/WebJobs.Script.Tests.Integration/Management/InstanceControllerTests.cs b/test/WebJobs.Script.Tests.Integration/Management/InstanceControllerTests.cs index e411a9b78c..f653283fdd 100644 --- a/test/WebJobs.Script.Tests.Integration/Management/InstanceControllerTests.cs +++ b/test/WebJobs.Script.Tests.Integration/Management/InstanceControllerTests.cs @@ -28,9 +28,6 @@ namespace Microsoft.Azure.WebJobs.Script.Tests.Managment [Trait(TestTraits.Group, TestTraits.ContainerInstanceTests)] public class InstanceControllerTests { - [SuppressMessage("Microsoft.Security", "CS002:SecretInNextLine", Justification = "Fake key for testing purposes.")] - private const string ContainerEncryptionKey = "/a/vXvWJ3Hzgx4PFxlDUJJhQm5QVyGiu0NNLFm/ZMMg="; - private readonly TestOptionsFactory _optionsFactory = new TestOptionsFactory(new ScriptApplicationHostOptions()); private readonly Mock _runFromPackageHandler; @@ -82,14 +79,14 @@ public async Task Assign_MSISpecializationFailure_ReturnsError() hostAssignmentContext.Environment[EnvironmentSettingNames.MsiEndpoint] = "http://localhost:8081"; hostAssignmentContext.Environment[EnvironmentSettingNames.MsiSecret] = "secret"; - var encryptedHostAssignmentValue = SimpleWebTokenHelper.Encrypt(JsonConvert.SerializeObject(hostAssignmentContext), ContainerEncryptionKey.ToKeyBytes()); + var encryptedHostAssignmentValue = SimpleWebTokenHelper.Encrypt(JsonConvert.SerializeObject(hostAssignmentContext), TestHelpers.EncryptionKey.ToKeyBytes()); var encryptedHostAssignmentContext = new EncryptedHostAssignmentContext() { EncryptedContext = encryptedHostAssignmentValue }; - environment.SetEnvironmentVariable(EnvironmentSettingNames.ContainerEncryptionKey, ContainerEncryptionKey); + environment.SetEnvironmentVariable(EnvironmentSettingNames.ContainerEncryptionKey, TestHelpers.EncryptionKey); IActionResult result = await instanceController.Assign(encryptedHostAssignmentContext); @@ -158,14 +155,14 @@ public async Task Assignment_Sets_Secrets_Context() hostAssignmentContext.Secrets = new FunctionAppSecrets(); hostAssignmentContext.IsWarmupRequest = false; // non-warmup Request - var encryptedHostAssignmentValue = SimpleWebTokenHelper.Encrypt(JsonConvert.SerializeObject(hostAssignmentContext), ContainerEncryptionKey.ToKeyBytes()); + var encryptedHostAssignmentValue = SimpleWebTokenHelper.Encrypt(JsonConvert.SerializeObject(hostAssignmentContext), TestHelpers.EncryptionKey.ToKeyBytes()); var encryptedHostAssignmentContext = new EncryptedHostAssignmentContext() { EncryptedContext = encryptedHostAssignmentValue }; - environment.SetEnvironmentVariable(EnvironmentSettingNames.ContainerEncryptionKey, ContainerEncryptionKey); + environment.SetEnvironmentVariable(EnvironmentSettingNames.ContainerEncryptionKey, TestHelpers.EncryptionKey); await instanceController.Assign(encryptedHostAssignmentContext); Assert.NotNull(startupContextProvider.Context); @@ -211,14 +208,14 @@ public async Task Assignment_Does_Not_Set_Secrets_Context_For_Warmup_Request() hostAssignmentContext.Secrets = new FunctionAppSecrets(); hostAssignmentContext.IsWarmupRequest = true; // Warmup Request - var encryptedHostAssignmentValue = SimpleWebTokenHelper.Encrypt(JsonConvert.SerializeObject(hostAssignmentContext), ContainerEncryptionKey.ToKeyBytes()); + var encryptedHostAssignmentValue = SimpleWebTokenHelper.Encrypt(JsonConvert.SerializeObject(hostAssignmentContext), TestHelpers.EncryptionKey.ToKeyBytes()); var encryptedHostAssignmentContext = new EncryptedHostAssignmentContext() { EncryptedContext = encryptedHostAssignmentValue }; - environment.SetEnvironmentVariable(EnvironmentSettingNames.ContainerEncryptionKey, ContainerEncryptionKey); + environment.SetEnvironmentVariable(EnvironmentSettingNames.ContainerEncryptionKey, TestHelpers.EncryptionKey); await instanceController.Assign(encryptedHostAssignmentContext); Assert.Null(startupContextProvider.Context); @@ -252,14 +249,14 @@ public async Task Assignment_Invokes_InstanceManager_Methods_For_Warmup_Requests var encryptedHostAssignmentValue = SimpleWebTokenHelper.Encrypt(JsonConvert.SerializeObject(hostAssignmentContext), - ContainerEncryptionKey.ToKeyBytes()); + TestHelpers.EncryptionKey.ToKeyBytes()); var encryptedHostAssignmentContext = new EncryptedHostAssignmentContext() { EncryptedContext = encryptedHostAssignmentValue }; - environment.SetEnvironmentVariable(EnvironmentSettingNames.ContainerEncryptionKey, ContainerEncryptionKey); + environment.SetEnvironmentVariable(EnvironmentSettingNames.ContainerEncryptionKey, TestHelpers.EncryptionKey); await instanceController.Assign(encryptedHostAssignmentContext); diff --git a/test/WebJobs.Script.Tests.Integration/Management/KubernetesPodControllerTests.cs b/test/WebJobs.Script.Tests.Integration/Management/KubernetesPodControllerTests.cs index c22941aa01..a0af83133e 100644 --- a/test/WebJobs.Script.Tests.Integration/Management/KubernetesPodControllerTests.cs +++ b/test/WebJobs.Script.Tests.Integration/Management/KubernetesPodControllerTests.cs @@ -28,9 +28,6 @@ namespace Microsoft.Azure.WebJobs.Script.Tests.Managment [Trait(TestTraits.Group, TestTraits.ContainerInstanceTests)] public class KubernetesPodControllerTests { - [SuppressMessage("Microsoft.Security", "CS002:SecretInNextLine", Justification = "Fake key for testing purposes.")] - private const string PodEncryptionKey = "/a/vXvWJ3Hzgx4PFxlDUJJhQm5QVyGiu0NNLFm/ZMMg="; - private readonly TestOptionsFactory _optionsFactory = new TestOptionsFactory(new ScriptApplicationHostOptions()); [Fact] @@ -74,14 +71,14 @@ public async Task Assignment_Succeeds_With_Encryption_Key() hostAssignmentContext.Secrets = new FunctionAppSecrets(); hostAssignmentContext.IsWarmupRequest = false; - var encryptedHostAssignmentValue = SimpleWebTokenHelper.Encrypt(JsonConvert.SerializeObject(hostAssignmentContext), PodEncryptionKey.ToKeyBytes()); + var encryptedHostAssignmentValue = SimpleWebTokenHelper.Encrypt(JsonConvert.SerializeObject(hostAssignmentContext), TestHelpers.EncryptionKey.ToKeyBytes()); var encryptedHostAssignmentContext = new EncryptedHostAssignmentContext() { EncryptedContext = encryptedHostAssignmentValue }; - environment.SetEnvironmentVariable(EnvironmentSettingNames.PodEncryptionKey, PodEncryptionKey); + environment.SetEnvironmentVariable(EnvironmentSettingNames.PodEncryptionKey, TestHelpers.EncryptionKey); environment.SetEnvironmentVariable(EnvironmentSettingNames.KubernetesServiceHost, "http://localhost:80"); environment.SetEnvironmentVariable(EnvironmentSettingNames.PodNamespace, "k8se-apps"); @@ -131,7 +128,7 @@ public async Task Assignment_Fails_Without_Encryption_Key() hostAssignmentContext.Secrets = new FunctionAppSecrets(); hostAssignmentContext.IsWarmupRequest = false; - var encryptedHostAssignmentValue = SimpleWebTokenHelper.Encrypt(JsonConvert.SerializeObject(hostAssignmentContext), PodEncryptionKey.ToKeyBytes()); + var encryptedHostAssignmentValue = SimpleWebTokenHelper.Encrypt(JsonConvert.SerializeObject(hostAssignmentContext), TestHelpers.EncryptionKey.ToKeyBytes()); var encryptedHostAssignmentContext = new EncryptedHostAssignmentContext() { diff --git a/test/WebJobs.Script.Tests.Integration/Management/MeshServiceClientTests.cs b/test/WebJobs.Script.Tests.Integration/Management/MeshServiceClientTests.cs index dde5f12e62..c6bfd44d5f 100644 --- a/test/WebJobs.Script.Tests.Integration/Management/MeshServiceClientTests.cs +++ b/test/WebJobs.Script.Tests.Integration/Management/MeshServiceClientTests.cs @@ -3,10 +3,10 @@ using System; using System.Collections.Generic; -using System.Diagnostics.CodeAnalysis; using System.Linq; using System.Net; using System.Net.Http; +using System.Text; using System.Threading; using System.Threading.Tasks; using Microsoft.Azure.WebJobs.Script.WebHost.Management; @@ -21,9 +21,6 @@ namespace Microsoft.Azure.WebJobs.Script.Tests.Integration.Management { public class MeshServiceClientTests { - [SuppressMessage("Microsoft.Security", "CS002:SecretInNextLine", Justification = "Fake key for testing purposes.")] - private const string ConnectionString = "DefaultEndpointsProtocol=https;AccountName=storageaccount;AccountKey=whXtW6WP8QTh84TT5wdjgzeFTj7Vc1aOiCVjTXohpE+jALoKOQ9nlQpj5C5zpgseVJxEVbaAhptP5j5DpaLgtA=="; - private const string MeshInitUri = "http://localhost:8954/"; private const string ContainerName = "MockContainerName"; private readonly IMeshServiceClient _meshServiceClient; @@ -83,9 +80,7 @@ public async Task MountsCifsShare() StatusCode = HttpStatusCode.OK }); - - - await _meshServiceClient.MountCifs(ConnectionString, "sharename", "/data"); + await _meshServiceClient.MountCifs(TestHelpers.StorageConnectionString, "sharename", "/data"); await Task.Delay(500); diff --git a/test/WebJobs.Script.Tests.Shared/TestHelpers.Constants.cs b/test/WebJobs.Script.Tests.Shared/TestHelpers.Constants.cs new file mode 100644 index 0000000000..75f0682ce3 --- /dev/null +++ b/test/WebJobs.Script.Tests.Shared/TestHelpers.Constants.cs @@ -0,0 +1,46 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. + +using System; +using System.IO; +using System.Security.Cryptography; +using System.Text; + +namespace Microsoft.Azure.WebJobs.Script.Tests +{ + public static partial class TestHelpers + { +#if DEBUG + public const string BuildConfig = "debug"; +#else + public const string BuildConfig = "release"; +#endif + // Not a real storage account key. + public static readonly string StorageAccountKey = Convert.ToBase64String(Encoding.UTF8.GetBytes("PLACEHOLDER")); + + // Not a real connection string. + public static readonly string StorageConnectionString = $"DefaultEndpointsProtocol=http;AccountName=fakeaccount;AccountKey={StorageAccountKey}"; + + private static readonly Lazy _encryptionKey = new Lazy( + () => + { + using Aes aes = Aes.Create(); + aes.GenerateKey(); + return Convert.ToBase64String(aes.Key); + }); + + public static string EncryptionKey => _encryptionKey.Value; + + /// + /// Gets the common root directory that functions tests create temporary directories under. + /// This enables us to clean up test files by deleting this single directory. + /// + public static string FunctionsTestDirectory + { + get + { + return Path.Combine(Path.GetTempPath(), "FunctionsTest"); + } + } + } +} \ No newline at end of file diff --git a/test/WebJobs.Script.Tests.Shared/TestHelpers.cs b/test/WebJobs.Script.Tests.Shared/TestHelpers.cs index 700905712a..2b01586f2f 100644 --- a/test/WebJobs.Script.Tests.Shared/TestHelpers.cs +++ b/test/WebJobs.Script.Tests.Shared/TestHelpers.cs @@ -29,27 +29,9 @@ namespace Microsoft.Azure.WebJobs.Script.Tests { public static partial class TestHelpers { -#if DEBUG - public const string BuildConfig = "debug"; -#else - public const string BuildConfig = "release"; -#endif - private const string Chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; private static readonly Random Random = new Random(); - /// - /// Gets the common root directory that functions tests create temporary directories under. - /// This enables us to clean up test files by deleting this single directory. - /// - public static string FunctionsTestDirectory - { - get - { - return Path.Combine(Path.GetTempPath(), "FunctionsTest"); - } - } - public static Task WaitOneAsync(this WaitHandle waitHandle) { if (waitHandle == null) diff --git a/test/WebJobs.Script.Tests.Shared/WebJobs.Script.Tests.Shared.projitems b/test/WebJobs.Script.Tests.Shared/WebJobs.Script.Tests.Shared.projitems index 8876f04069..ef611083c7 100644 --- a/test/WebJobs.Script.Tests.Shared/WebJobs.Script.Tests.Shared.projitems +++ b/test/WebJobs.Script.Tests.Shared/WebJobs.Script.Tests.Shared.projitems @@ -31,6 +31,7 @@ + diff --git a/test/WebJobs.Script.Tests/Security/SecretManagerTests.cs b/test/WebJobs.Script.Tests/Security/SecretManagerTests.cs index febb6a0b5e..b838d66a30 100644 --- a/test/WebJobs.Script.Tests/Security/SecretManagerTests.cs +++ b/test/WebJobs.Script.Tests/Security/SecretManagerTests.cs @@ -19,7 +19,6 @@ using Microsoft.Azure.WebJobs.Script.WebHost.Models; using Microsoft.Azure.WebJobs.Script.WebHost.Properties; using Microsoft.Azure.WebJobs.Script.WebHost.Security; -using Microsoft.Azure.WebJobs.Script.WebHost.Storage; using Microsoft.Extensions.Logging; using Microsoft.WebJobs.Script.Tests; using Moq; @@ -34,8 +33,6 @@ public class SecretManagerTests { private const int TestSentinelWatcherInitializationDelayMS = 50; - [SuppressMessage("Microsoft.Security", "CS002:SecretInNextLine", Justification="Fake key for testing purposes.")] - private const string TestEncryptionKey = "/a/vXvWJ3Hzgx4PFxlDUJJhQm5QVyGiu0NNLFm/ZMMg="; private readonly HostNameProvider _hostNameProvider; private readonly TestEnvironment _testEnvironment; private readonly TestLoggerProvider _loggerProvider; @@ -63,7 +60,7 @@ public async Task CachedSecrets_UsedWhenPresent() { string startupContextPath = Path.Combine(directory.Path, Guid.NewGuid().ToString()); _testEnvironment.SetEnvironmentVariable(EnvironmentSettingNames.AzureWebsiteStartupContextCache, startupContextPath); - _testEnvironment.SetEnvironmentVariable(EnvironmentSettingNames.WebSiteAuthEncryptionKey, TestEncryptionKey); + _testEnvironment.SetEnvironmentVariable(EnvironmentSettingNames.WebSiteAuthEncryptionKey, TestHelpers.EncryptionKey); WriteStartContextCache(startupContextPath); @@ -120,7 +117,7 @@ public async Task GetAuthorizationLevelOrNullAsync_ReturnsExpectedResult(string { string startupContextPath = Path.Combine(directory.Path, Guid.NewGuid().ToString()); _testEnvironment.SetEnvironmentVariable(EnvironmentSettingNames.AzureWebsiteStartupContextCache, startupContextPath); - _testEnvironment.SetEnvironmentVariable(EnvironmentSettingNames.WebSiteAuthEncryptionKey, TestEncryptionKey); + _testEnvironment.SetEnvironmentVariable(EnvironmentSettingNames.WebSiteAuthEncryptionKey, TestHelpers.EncryptionKey); WriteStartContextCache(startupContextPath); @@ -181,7 +178,7 @@ private FunctionAppSecrets WriteStartContextCache(string path) }; string json = JsonConvert.SerializeObject(context); - var encryptionKey = Convert.FromBase64String(TestEncryptionKey); + var encryptionKey = Convert.FromBase64String(TestHelpers.EncryptionKey); string encryptedJson = SimpleWebTokenHelper.Encrypt(json, encryptionKey); File.WriteAllText(path, encryptedJson); diff --git a/test/WebJobs.Script.Tests/StartupContextProviderTests.cs b/test/WebJobs.Script.Tests/StartupContextProviderTests.cs index 0801f1789a..3f970ea726 100644 --- a/test/WebJobs.Script.Tests/StartupContextProviderTests.cs +++ b/test/WebJobs.Script.Tests/StartupContextProviderTests.cs @@ -20,9 +20,6 @@ namespace Microsoft.Azure.WebJobs.Script.Tests { public class StartupContextProviderTests { - [SuppressMessage("Microsoft.Security", "CS002:SecretInNextLine", Justification="Fake key for testing purposes.")] - private const string TestEncryptionKey = "/a/vXvWJ3Hzgx4PFxlDUJJhQm5QVyGiu0NNLFm/ZMMg="; - private readonly FunctionAppSecrets _secrets; private readonly StartupContextProvider _startupContextProvider; private readonly TestEnvironment _environment; @@ -72,7 +69,7 @@ public StartupContextProviderTests() _loggerProvider = new TestLoggerProvider(); loggerFactory.AddProvider(_loggerProvider); - _environment.SetEnvironmentVariable(EnvironmentSettingNames.WebSiteAuthEncryptionKey, TestEncryptionKey); + _environment.SetEnvironmentVariable(EnvironmentSettingNames.WebSiteAuthEncryptionKey, TestHelpers.EncryptionKey); _startupContextProvider = new StartupContextProvider(_environment, loggerFactory.CreateLogger()); }