diff --git a/tools/test-proxy/Azure.Sdk.Tools.TestProxy.Tests/RecordingHandlerTests.cs b/tools/test-proxy/Azure.Sdk.Tools.TestProxy.Tests/RecordingHandlerTests.cs index 54879406e75..f2be9e6e9cb 100644 --- a/tools/test-proxy/Azure.Sdk.Tools.TestProxy.Tests/RecordingHandlerTests.cs +++ b/tools/test-proxy/Azure.Sdk.Tools.TestProxy.Tests/RecordingHandlerTests.cs @@ -307,7 +307,7 @@ public async Task TestLoadOfAbsoluteRecording() var playbackSession = recordingHandler.PlaybackSessions.First(); var entry = playbackSession.Value.Session.Entries.First(); - Assert.Equal("https://REDACTED.microsoftonline.com/12345678-1234-1234-1234-123456789012/oauth2/v2.0/token", entry.RequestUri); + Assert.Equal("https://login.microsoftonline.com/12345678-1234-1234-1234-123456789012/oauth2/v2.0/token", entry.RequestUri); } [Fact] @@ -323,7 +323,7 @@ public async Task TestLoadOfRelativeRecording() var playbackSession = recordingHandler.PlaybackSessions.First(); var entry = playbackSession.Value.Session.Entries.First(); - Assert.Equal("https://REDACTED.microsoftonline.com/12345678-1234-1234-1234-123456789012/oauth2/v2.0/token", entry.RequestUri); + Assert.Equal("https://login.microsoftonline.com/12345678-1234-1234-1234-123456789012/oauth2/v2.0/token", entry.RequestUri); } [Fact] diff --git a/tools/test-proxy/Azure.Sdk.Tools.TestProxy.Tests/SanitizerTests.cs b/tools/test-proxy/Azure.Sdk.Tools.TestProxy.Tests/SanitizerTests.cs index 4365589001d..d26089f1d32 100644 --- a/tools/test-proxy/Azure.Sdk.Tools.TestProxy.Tests/SanitizerTests.cs +++ b/tools/test-proxy/Azure.Sdk.Tools.TestProxy.Tests/SanitizerTests.cs @@ -50,6 +50,19 @@ public void SanitizerDecodesUnicodeAmpersandSanitizesClientIdAndSecret() Assert.Equal("client_id=Sanitized&grant_type=client_credentials&client_info=1&client_secret=Sanitized&claims=%7B%22access_token=blahblah", Encoding.UTF8.GetString(session.Session.Entries[0].Request.Body)); } + [Fact] + public void EnsureSASCleanupDoesntOverrunInXML() + { + var sanitizerDictionary = new SanitizerDictionary(); + var sessionwithXmlBody = TestHelpers.LoadRecordSession("Test.RecordEntries/xml_body_with_sas_present.json"); + + Assert.True(sanitizerDictionary.Sanitizers.TryGetValue("AZSDK1007", out RegisteredSanitizer SASURISanitizer)); + + sessionwithXmlBody.Session.Sanitize(SASURISanitizer.Sanitizer); + + Assert.Contains("1024/1024", Encoding.UTF8.GetString(sessionwithXmlBody.Session.Entries[0].Response.Body)); + } + [Fact] public void OauthResponseSanitizerCleansNonV2AuthRequest() { diff --git a/tools/test-proxy/Azure.Sdk.Tools.TestProxy.Tests/Test.RecordEntries/xml_body_with_sas_present.json b/tools/test-proxy/Azure.Sdk.Tools.TestProxy.Tests/Test.RecordEntries/xml_body_with_sas_present.json new file mode 100644 index 00000000000..995d4493d55 --- /dev/null +++ b/tools/test-proxy/Azure.Sdk.Tools.TestProxy.Tests/Test.RecordEntries/xml_body_with_sas_present.json @@ -0,0 +1,30 @@ +{ + "Entries": [ + { + "RequestUri": "https://REDACTED.blob.core.windows.net/blockblobclienttestsynccopyfromuri?comp=list&include=copy&prefix=destS72lXCxNKX&restype=container", + "RequestMethod": "GET", + "RequestHeaders": { + "Authorization": "Sanitized", + "User-Agent": "azsdk-cpp-storage-blobs/12.11.0-beta.2 (Windows 10 Enterprise 6.3 22631 22621.1.amd64fre.ni_release.220506-1250)", + "x-ms-client-request-id": "Sanitized", + "x-ms-date": "Sun, 28 Apr 2024 06:31:46 GMT", + "x-ms-version": "2023-11-03" + }, + "RequestBody": null, + "StatusCode": 200, + "ResponseHeaders": { + "Content-Type": "application/xml", + "Date": "Sun, 28 Apr 2024 06:31:45 GMT", + "Server": [ + "Windows-Azure-Blob/1.0", + "Microsoft-HTTPAPI/2.0" + ], + "Transfer-Encoding": "chunked", + "x-ms-client-request-id": "Sanitized", + "x-ms-request-id": "Sanitized", + "x-ms-version": "2023-11-03" + }, + "ResponseBody": "\uFEFFdestS72lXCxNKXdestS72lXCxNKX2024-04-28T06:31:45.7176515ZtrueSun, 28 Apr 2024 06:31:45 GMTSun, 28 Apr 2024 06:31:45 GMT0x8DC674CE03A6C6F1024application/octet-streamiu0B5sKKllE=7Fnk5RibvrmdtnSTCz3FWA==BlockBlobHottrueunlockedavailabled49efb17-b054-4515-aac3-6e301ee771cehttps://afakeblobname.blob.core.windows.net:443/blockblobclienttestsynccopyfromuri/sourceC4GbldEmXi?se=2024-04-19T09%3a42%3a44Z&sp=xxx&spr=https%2chttp&sr=c&sv=2023-11-03success1024/1024Fri, 26 Apr 2024 09:42:44 GMTtrue" + } + ] +} \ No newline at end of file diff --git a/tools/test-proxy/Azure.Sdk.Tools.TestProxy/Common/ModifiableRecordSession.cs b/tools/test-proxy/Azure.Sdk.Tools.TestProxy/Common/ModifiableRecordSession.cs index c5246e1fd78..96d9952a318 100644 --- a/tools/test-proxy/Azure.Sdk.Tools.TestProxy/Common/ModifiableRecordSession.cs +++ b/tools/test-proxy/Azure.Sdk.Tools.TestProxy/Common/ModifiableRecordSession.cs @@ -29,6 +29,8 @@ public ModifiableRecordSession(RecordSession session, SanitizerDictionary saniti public string Path { get; set; } + public bool IsSanitized { get; set; } + public HttpClient Client { get; set; } public List AdditionalTransforms { get; } = new List(); diff --git a/tools/test-proxy/Azure.Sdk.Tools.TestProxy/Common/SanitizerDictionary.cs b/tools/test-proxy/Azure.Sdk.Tools.TestProxy/Common/SanitizerDictionary.cs index c8cf6e7e8ec..fec616d4767 100644 --- a/tools/test-proxy/Azure.Sdk.Tools.TestProxy/Common/SanitizerDictionary.cs +++ b/tools/test-proxy/Azure.Sdk.Tools.TestProxy/Common/SanitizerDictionary.cs @@ -36,7 +36,7 @@ public static ulong GetNextId() public class SanitizerDictionary { - private ConcurrentDictionary Sanitizers = new ConcurrentDictionary(); + public ConcurrentDictionary Sanitizers = new ConcurrentDictionary(); // we have to know which sanitizers are session only // so that when we start a new recording we can properly diff --git a/tools/test-proxy/Azure.Sdk.Tools.TestProxy/RecordingHandler.cs b/tools/test-proxy/Azure.Sdk.Tools.TestProxy/RecordingHandler.cs index faae4aa2f3a..3d39a4f41ba 100644 --- a/tools/test-proxy/Azure.Sdk.Tools.TestProxy/RecordingHandler.cs +++ b/tools/test-proxy/Azure.Sdk.Tools.TestProxy/RecordingHandler.cs @@ -398,12 +398,6 @@ public async Task StartPlaybackAsync(string sessionId, HttpResponse outgoingResp { Path = path }; - - var sanitizers = SanitizerRegistry.GetSanitizers(); - foreach (RecordedTestSanitizer sanitizer in sanitizers) - { - session.Session.Sanitize(sanitizer); - } } if (!PlaybackSessions.TryAdd(id, session)) @@ -463,6 +457,17 @@ public async Task HandlePlaybackRequest(string recordingId, HttpRequest incoming var sanitizers = SanitizerRegistry.GetSanitizers(session); + // we don't need to re-sanitize with recording-applicable sanitizers every time. just the very first one + if (!session.IsSanitized) + { + session.IsSanitized = true; + + foreach (RecordedTestSanitizer sanitizer in sanitizers) + { + session.Session.Sanitize(sanitizer); + } + } + DebugLogger.LogRequestDetails(incomingRequest, sanitizers); var entry = (await CreateEntryAsync(incomingRequest).ConfigureAwait(false)).Item1;