From 365557c05a8c9b398c0f0f0c5cd7f981016eb185 Mon Sep 17 00:00:00 2001 From: CarloToso <105941898+CarloToso@users.noreply.github.com> Date: Thu, 17 Nov 2022 11:18:20 +0100 Subject: [PATCH 1/9] Detect insecure redirection --- .../utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs index 85932f7eb86..bed78efa76a 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs @@ -1558,6 +1558,14 @@ protected override void ProcessRecord() OutFile = null; } + // Detect insecure redirection + if (response.RequestMessage.RequestUri.Scheme == "https" && response.Headers.Location?.Scheme == "http") + { + ErrorRecord er = new(new InvalidOperationException(), "InsecureRedirection", ErrorCategory.InvalidOperation, request); + er.ErrorDetails = new ErrorDetails(WebCmdletStrings.InsecureRedirection; + WriteError(er); + } + if (ShouldCheckHttpStatus && !_isSuccess) { string message = string.Format(CultureInfo.CurrentCulture, WebCmdletStrings.ResponseStatusCodeFailure, From b1f702c5d3f70a7d0e4e257d3d1b4800d586f0c3 Mon Sep 17 00:00:00 2001 From: CarloToso <105941898+CarloToso@users.noreply.github.com> Date: Thu, 17 Nov 2022 11:35:50 +0100 Subject: [PATCH 2/9] Add error --- .../resources/WebCmdletStrings.resx | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/Microsoft.PowerShell.Commands.Utility/resources/WebCmdletStrings.resx b/src/Microsoft.PowerShell.Commands.Utility/resources/WebCmdletStrings.resx index bea0ae7d28a..608f7aba06f 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/resources/WebCmdletStrings.resx +++ b/src/Microsoft.PowerShell.Commands.Utility/resources/WebCmdletStrings.resx @@ -159,12 +159,15 @@ Cannot convert the JSON string because a dictionary that was converted from the string contains the duplicated key '{0}'. - - Cannot convert the JSON string because it contains keys with different casing. Please use the -AsHashTable switch instead. The key that was attempted to be added to the existing key '{0}' was '{1}'. - The response content cannot be parsed because the Internet Explorer engine is not available, or Internet Explorer's first-launch configuration is not complete. Specify the UseBasicParsing parameter and try again. + + Cannot follow an insecure redirect. + + + Cannot convert the JSON string because it contains keys with different casing. Please use the -AsHashTable switch instead. The key that was attempted to be added to the existing key '{0}' was '{1}'. + The maximum redirection count has been exceeded. To increase the number of redirections allowed, supply a higher value to the -MaximumRedirection parameter. From ba11ffea744e414c93ff3d0e860436c24a289fba Mon Sep 17 00:00:00 2001 From: CarloToso <105941898+CarloToso@users.noreply.github.com> Date: Thu, 17 Nov 2022 11:42:02 +0100 Subject: [PATCH 3/9] Better error --- .../resources/WebCmdletStrings.resx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Microsoft.PowerShell.Commands.Utility/resources/WebCmdletStrings.resx b/src/Microsoft.PowerShell.Commands.Utility/resources/WebCmdletStrings.resx index 608f7aba06f..7f70e5d30ed 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/resources/WebCmdletStrings.resx +++ b/src/Microsoft.PowerShell.Commands.Utility/resources/WebCmdletStrings.resx @@ -163,7 +163,7 @@ The response content cannot be parsed because the Internet Explorer engine is not available, or Internet Explorer's first-launch configuration is not complete. Specify the UseBasicParsing parameter and try again. - Cannot follow an insecure redirect. + Cannot follow an insecure redirect by default. Reissue the command specifying the AllowInsecureRedirect parameter. Cannot convert the JSON string because it contains keys with different casing. Please use the -AsHashTable switch instead. The key that was attempted to be added to the existing key '{0}' was '{1}'. From aa403e5cdb3db13210e91b99068891c465e15684 Mon Sep 17 00:00:00 2001 From: CarloToso <105941898+CarloToso@users.noreply.github.com> Date: Thu, 17 Nov 2022 15:47:44 +0100 Subject: [PATCH 4/9] Fix error message --- .../utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs | 2 +- .../resources/WebCmdletStrings.resx | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs index bed78efa76a..41b0eeaee13 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs @@ -1562,7 +1562,7 @@ protected override void ProcessRecord() if (response.RequestMessage.RequestUri.Scheme == "https" && response.Headers.Location?.Scheme == "http") { ErrorRecord er = new(new InvalidOperationException(), "InsecureRedirection", ErrorCategory.InvalidOperation, request); - er.ErrorDetails = new ErrorDetails(WebCmdletStrings.InsecureRedirection; + er.ErrorDetails = new ErrorDetails(WebCmdletStrings.InsecureRedirection); WriteError(er); } diff --git a/src/Microsoft.PowerShell.Commands.Utility/resources/WebCmdletStrings.resx b/src/Microsoft.PowerShell.Commands.Utility/resources/WebCmdletStrings.resx index 7f70e5d30ed..52dfa683188 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/resources/WebCmdletStrings.resx +++ b/src/Microsoft.PowerShell.Commands.Utility/resources/WebCmdletStrings.resx @@ -162,8 +162,8 @@ The response content cannot be parsed because the Internet Explorer engine is not available, or Internet Explorer's first-launch configuration is not complete. Specify the UseBasicParsing parameter and try again. - - Cannot follow an insecure redirect by default. Reissue the command specifying the AllowInsecureRedirect parameter. + + Cannot follow an insecure redirection by default. Reissue the command specifying the AllowInsecureRedirect parameter. Cannot convert the JSON string because it contains keys with different casing. Please use the -AsHashTable switch instead. The key that was attempted to be added to the existing key '{0}' was '{1}'. From 2bb1ceec4368441e74a6179ef40fc3816652ba21 Mon Sep 17 00:00:00 2001 From: CarloToso <105941898+CarloToso@users.noreply.github.com> Date: Thu, 17 Nov 2022 19:56:30 +0100 Subject: [PATCH 5/9] Reword Error --- .../resources/WebCmdletStrings.resx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Microsoft.PowerShell.Commands.Utility/resources/WebCmdletStrings.resx b/src/Microsoft.PowerShell.Commands.Utility/resources/WebCmdletStrings.resx index 52dfa683188..a9628c647e3 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/resources/WebCmdletStrings.resx +++ b/src/Microsoft.PowerShell.Commands.Utility/resources/WebCmdletStrings.resx @@ -163,7 +163,7 @@ The response content cannot be parsed because the Internet Explorer engine is not available, or Internet Explorer's first-launch configuration is not complete. Specify the UseBasicParsing parameter and try again. - Cannot follow an insecure redirection by default. Reissue the command specifying the AllowInsecureRedirect parameter. + Cannot follow an insecure redirection by default. Reissue the command specifying the -AllowInsecureRedirect switch. Cannot convert the JSON string because it contains keys with different casing. Please use the -AsHashTable switch instead. The key that was attempted to be added to the existing key '{0}' was '{1}'. From 3f33a244ec707b2e09ac650e265d1849fb08daeb Mon Sep 17 00:00:00 2001 From: CarloToso <105941898+CarloToso@users.noreply.github.com> Date: Mon, 9 Jan 2023 18:21:06 +0100 Subject: [PATCH 6/9] WriteError -> ThrowTerminatingError --- .../utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs index 51c73d604aa..4eb521f0fb1 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs @@ -1525,7 +1525,7 @@ WebSession.Headers is not null && { ErrorRecord er = new(new InvalidOperationException(), "InsecureRedirection", ErrorCategory.InvalidOperation, request); er.ErrorDetails = new ErrorDetails(WebCmdletStrings.InsecureRedirection); - WriteError(er); + ThrowTerminatingError(er); } if (ShouldCheckHttpStatus && !_isSuccess) From 6ad7fc9a1baf8262046324114873e5ecb0663eae Mon Sep 17 00:00:00 2001 From: CarloToso <105941898+CarloToso@users.noreply.github.com> Date: Fri, 13 Jan 2023 19:40:42 +0100 Subject: [PATCH 7/9] Update and add !AllowInsecureRedirect --- .../utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs index 7c3a72155f9..6a1623b7596 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs @@ -1486,7 +1486,7 @@ protected override void ProcessRecord() } // Detect insecure redirection - if (response.RequestMessage.RequestUri.Scheme == "https" && response.Headers.Location?.Scheme == "http") + if (!AllowInsecureRedirect && response.RequestMessage.RequestUri.Scheme == "https" && response.Headers.Location?.Scheme == "http") { ErrorRecord er = new(new InvalidOperationException(), "InsecureRedirection", ErrorCategory.InvalidOperation, request); er.ErrorDetails = new ErrorDetails(WebCmdletStrings.InsecureRedirection); From 11d6ed920e9de1b3a1060e76746cb5a420697f42 Mon Sep 17 00:00:00 2001 From: CarloToso <105941898+CarloToso@users.noreply.github.com> Date: Fri, 13 Jan 2023 23:23:44 +0100 Subject: [PATCH 8/9] fix tests --- .../Microsoft.PowerShell.Utility/WebCmdlets.Tests.ps1 | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/powershell/Modules/Microsoft.PowerShell.Utility/WebCmdlets.Tests.ps1 b/test/powershell/Modules/Microsoft.PowerShell.Utility/WebCmdlets.Tests.ps1 index 285be044eb4..c6b421623c0 100644 --- a/test/powershell/Modules/Microsoft.PowerShell.Utility/WebCmdlets.Tests.ps1 +++ b/test/powershell/Modules/Microsoft.PowerShell.Utility/WebCmdlets.Tests.ps1 @@ -893,7 +893,7 @@ Describe "Invoke-WebRequest tests" -Tags "Feature", "RequireAdminOnWindows" { $response.Error | Should -BeNullOrEmpty $response.Content.Headers."Authorization" | Should -BeExactly "test" } - + It "Validates Invoke-WebRequest with -PreserveAuthorizationOnRedirect respects -MaximumRedirection on redirect: " -TestCases $redirectTests { param($redirectType, $redirectedMethod) $uri = Get-WebListenerUrl -Test 'Redirect' -TestValue '3' -Query @{type = $redirectType} @@ -990,7 +990,7 @@ Describe "Invoke-WebRequest tests" -Tags "Feature", "RequireAdminOnWindows" { $command = "Invoke-WebRequest -Uri '$uri' -SkipCertificateCheck" $result = ExecuteWebCommand -command $command - $result.Error.FullyQualifiedErrorId | Should -Be "WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeWebRequestCommand" + $result.Error.FullyQualifiedErrorId | Should -Be "InsecureRedirectException,Microsoft.PowerShell.Commands.InvokeWebRequestCommand" } } @@ -2683,7 +2683,7 @@ Describe "Invoke-RestMethod tests" -Tags "Feature", "RequireAdminOnWindows" { $command = "Invoke-RestMethod -Uri '$uri' -SkipCertificateCheck" $result = ExecuteWebCommand -command $command - $result.Error.FullyQualifiedErrorId | Should -Be "WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeRestMethodCommand" + $result.Error.FullyQualifiedErrorId | Should -Be "InsecureRedirectException,Microsoft.PowerShell.Commands.InvokeRestMethodCommand" } #endregion Redirect tests From 38269a7d10a4d3a54247a99e5d6fc0024f0708be Mon Sep 17 00:00:00 2001 From: CarloToso <105941898+CarloToso@users.noreply.github.com> Date: Sat, 14 Jan 2023 01:18:48 +0100 Subject: [PATCH 9/9] fix test error --- .../Modules/Microsoft.PowerShell.Utility/WebCmdlets.Tests.ps1 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/powershell/Modules/Microsoft.PowerShell.Utility/WebCmdlets.Tests.ps1 b/test/powershell/Modules/Microsoft.PowerShell.Utility/WebCmdlets.Tests.ps1 index c6b421623c0..cb721795f24 100644 --- a/test/powershell/Modules/Microsoft.PowerShell.Utility/WebCmdlets.Tests.ps1 +++ b/test/powershell/Modules/Microsoft.PowerShell.Utility/WebCmdlets.Tests.ps1 @@ -990,7 +990,7 @@ Describe "Invoke-WebRequest tests" -Tags "Feature", "RequireAdminOnWindows" { $command = "Invoke-WebRequest -Uri '$uri' -SkipCertificateCheck" $result = ExecuteWebCommand -command $command - $result.Error.FullyQualifiedErrorId | Should -Be "InsecureRedirectException,Microsoft.PowerShell.Commands.InvokeWebRequestCommand" + $result.Error.FullyQualifiedErrorId | Should -Be "InsecureRedirection,Microsoft.PowerShell.Commands.InvokeWebRequestCommand" } } @@ -2683,7 +2683,7 @@ Describe "Invoke-RestMethod tests" -Tags "Feature", "RequireAdminOnWindows" { $command = "Invoke-RestMethod -Uri '$uri' -SkipCertificateCheck" $result = ExecuteWebCommand -command $command - $result.Error.FullyQualifiedErrorId | Should -Be "InsecureRedirectException,Microsoft.PowerShell.Commands.InvokeRestMethodCommand" + $result.Error.FullyQualifiedErrorId | Should -Be "InsecureRedirection,Microsoft.PowerShell.Commands.InvokeRestMethodCommand" } #endregion Redirect tests