diff --git a/RELEASENOTES.md b/RELEASENOTES.md index 25e3482e7..589134c8a 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -1 +1,2 @@ - Redact `X-Amz-Credential` querystring parameters in AWS S3 URLs included in logs +- When redacting sensitive patterns in log output, use a non-case sensitive search \ No newline at end of file diff --git a/src/Octoshift/Services/OctoLogger.cs b/src/Octoshift/Services/OctoLogger.cs index 1e4a98ef9..4e05f4752 100644 --- a/src/Octoshift/Services/OctoLogger.cs +++ b/src/Octoshift/Services/OctoLogger.cs @@ -97,7 +97,7 @@ private string Redact(string msg) foreach (var redactionPattern in _redactionPatterns) { - result = Regex.Replace(result, redactionPattern, "***"); + result = Regex.Replace(result, redactionPattern, "***", RegexOptions.IgnoreCase); } return result; diff --git a/src/OctoshiftCLI.Tests/Octoshift/Services/OctoLoggerTests.cs b/src/OctoshiftCLI.Tests/Octoshift/Services/OctoLoggerTests.cs index 602b8d385..ab97d0a10 100644 --- a/src/OctoshiftCLI.Tests/Octoshift/Services/OctoLoggerTests.cs +++ b/src/OctoshiftCLI.Tests/Octoshift/Services/OctoLoggerTests.cs @@ -63,25 +63,33 @@ public void Secrets_Should_Be_Masked_From_Logs_And_Console() [Fact] public void Ghes_Archive_Url_Tokens_Should_Be_Replaced_In_Logs_And_Console() { - var ghesArchiveUrl = "https://files.github.acmeinc.com/foo?token=foobar"; - - _octoLogger.Verbose = false; - _octoLogger.LogInformation($"Archive URL: {ghesArchiveUrl}"); - _octoLogger.LogVerbose($"Archive URL: {ghesArchiveUrl}"); - _octoLogger.LogWarning($"Archive URL: {ghesArchiveUrl}"); - _octoLogger.LogSuccess($"Archive URL: {ghesArchiveUrl}"); - _octoLogger.LogError($"Archive URL: {ghesArchiveUrl}"); - _octoLogger.LogError(new OctoshiftCliException($"Archive URL: {ghesArchiveUrl}")); - _octoLogger.LogError(new InvalidOperationException($"Archive URL: {ghesArchiveUrl}")); - - _octoLogger.Verbose = true; - _octoLogger.LogVerbose($"Archive URL: {ghesArchiveUrl}"); - - _consoleOutput.Should().NotContain(ghesArchiveUrl); - _logOutput.Should().NotContain(ghesArchiveUrl); - _verboseLogOutput.Should().NotContain(ghesArchiveUrl); - _consoleError.Should().NotContain(ghesArchiveUrl); + var variants = new[] + { + ghesArchiveUrl, + ghesArchiveUrl.ToUpper(), + ghesArchiveUrl.ToLower() + }; + + foreach (var variant in variants) + { + _octoLogger.Verbose = false; + _octoLogger.LogInformation($"Archive URL: {variant}"); + _octoLogger.LogVerbose($"Archive URL: {variant}"); + _octoLogger.LogWarning($"Archive URL: {variant}"); + _octoLogger.LogSuccess($"Archive URL: {variant}"); + _octoLogger.LogError($"Archive URL: {variant}"); + _octoLogger.LogError(new OctoshiftCliException($"Archive URL: {variant}")); + _octoLogger.LogError(new InvalidOperationException($"Archive URL: {variant}")); + + _octoLogger.Verbose = true; + _octoLogger.LogVerbose($"Archive URL: {variant}"); + + _consoleOutput.Should().NotContain(variant); + _logOutput.Should().NotContain(variant); + _verboseLogOutput.Should().NotContain(variant); + _consoleError.Should().NotContain(variant); + } _consoleOutput.Should().Contain("Archive URL: https://files.github.acmeinc.com/foo?token=***"); } @@ -89,25 +97,34 @@ public void Ghes_Archive_Url_Tokens_Should_Be_Replaced_In_Logs_And_Console() [Fact] public void Aws_Url_X_Aws_Credential_Parameters_Should_Be_Replaced_In_Logs_And_Console() { - var awsUrl = "https://example-s3-bucket-name.s3.amazonaws.com/uuid-uuid-uuid.tar.gz?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AAAAAAAAAAAAAAAAAAAAAAA&X-Amz-Date=20231025T104425Z&X-Amz-Expires=172800&X-Amz-Signature=AAAAAAAAAAAAAAAAAAAAAAA&X-Amz-SignedHeaders=host&actor_id=1&key_id=0&repo_id=0&response-content-disposition=filename%3Duuid-uuid-uuid.tar.gz&response-content-type=application%2Fx-gzip"; - - _octoLogger.Verbose = false; - _octoLogger.LogInformation($"Archive (metadata) download url: {awsUrl}"); - _octoLogger.LogVerbose($"Archive (metadata) download url: {awsUrl}"); - _octoLogger.LogWarning($"Archive (metadata) download url: {awsUrl}"); - _octoLogger.LogSuccess($"Archive (metadata) download url: {awsUrl}"); - _octoLogger.LogError($"Archive (metadata) download url: {awsUrl}"); - _octoLogger.LogError(new OctoshiftCliException($"Archive (metadata) download url: {awsUrl}")); - _octoLogger.LogError(new InvalidOperationException($"Archive (metadata) download url: {awsUrl}")); - - _octoLogger.Verbose = true; - _octoLogger.LogVerbose($"Archive (metadata) download url: {awsUrl}"); - - _consoleOutput.Should().NotContain(awsUrl); - _logOutput.Should().NotContain(awsUrl); - _verboseLogOutput.Should().NotContain(awsUrl); - _consoleError.Should().NotContain(awsUrl); + var variants = new[] + { + awsUrl, + awsUrl.ToUpper(), + awsUrl.ToLower() + }; + + foreach (var variant in variants) + { + _octoLogger.Verbose = false; + _octoLogger.LogInformation($"Archive (metadata) download url: {variant}"); + _octoLogger.LogVerbose($"Archive (metadata) download url: {variant}"); + _octoLogger.LogWarning($"Archive (metadata) download url: {variant}"); + _octoLogger.LogSuccess($"Archive (metadata) download url: {variant}"); + _octoLogger.LogError($"Archive (metadata) download url: {variant}"); + _octoLogger.LogError(new OctoshiftCliException($"Archive (metadata) download url: {variant}")); + _octoLogger.LogError(new InvalidOperationException($"Archive (metadata) download url: {variant}")); + _octoLogger.LogInformation($"Archive (metadata) download url: {variant.ToLower()}"); + + _octoLogger.Verbose = true; + _octoLogger.LogVerbose($"Archive (metadata) download url: {variant}"); + + _consoleOutput.Should().NotContain(variant); + _logOutput.Should().NotContain(variant); + _verboseLogOutput.Should().NotContain(variant); + _consoleError.Should().NotContain(variant); + } _consoleOutput.Should().Contain("https://example-s3-bucket-name.s3.amazonaws.com/uuid-uuid-uuid.tar.gz?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=***&X-Amz-Date=20231025T104425Z&X-Amz-Expires=172800&X-Amz-Signature=AAAAAAAAAAAAAAAAAAAAAAA&X-Amz-SignedHeaders=host&actor_id=1&key_id=0&repo_id=0&response-content-disposition=filename%3Duuid-uuid-uuid.tar.gz&response-content-type=application%2Fx-gzip"); }