Added check for existence of Location HTTP header before using it (#6560)

The HTTP RFC (https://tools.ietf.org/html/rfc7231#section-6.4) does not require a Location header to be present for redirects, thus it is required to check if the Location header is returned before using it.
This commit is contained in:
Florian Feldhaus 2018-04-08 14:51:17 +02:00 committed by Ilya
parent 48be625379
commit 94c8ce007d
2 changed files with 43 additions and 1 deletions

View file

@ -1287,7 +1287,7 @@ namespace Microsoft.PowerShell.Commands
_cancelToken = new CancellationTokenSource();
HttpResponseMessage response = client.SendAsync(request, HttpCompletionOption.ResponseHeadersRead, _cancelToken.Token).GetAwaiter().GetResult();
if (stripAuthorization && IsRedirectCode(response.StatusCode))
if (stripAuthorization && IsRedirectCode(response.StatusCode) && response.Headers.Location != null)
{
_cancelToken.Cancel();
_cancelToken = null;

View file

@ -822,6 +822,27 @@ Describe "Invoke-WebRequest tests" -Tags "Feature" {
$response.Content.Method | Should -Be $redirectedMethod
}
It "Validates Invoke-WebRequest handles responses without Location header for requests with Authorization header and redirect: <redirectType>" -TestCases $redirectTests {
param($redirectType, $redirectedMethod)
# Skip relative test as it is not a valid response type.
if ($redirectType -eq 'relative') { return }
# When an Authorization request header is present,
# and -PreserveAuthorizationOnRedirect is not present,
# PowerShell should throw an HTTP Response Exception
# for a redirect response which does not contain a Location response header.
# The correct redirect status code should be included in the exception.
$StatusCode = [int][System.Net.HttpStatusCode]$redirectType
$uri = Get-WebListenerUrl -Test Response -Query @{statuscode = $StatusCode}
$command = "Invoke-WebRequest -Uri '$uri' -Headers @{Authorization = 'foo'}"
$response = ExecuteWebCommand -command $command
$response.Error.Exception | Should -BeOfType 'Microsoft.PowerShell.Commands.HttpResponseException'
$response.Error.Exception.Response.StatusCode | Should -Be $StatusCode
$response.Error.Exception.Response.Headers.Location | Should -BeNullOrEmpty
}
#endregion Redirect tests
Context "Invoke-WebRequest SkipHeaderVerification Tests" {
@ -2137,6 +2158,27 @@ Describe "Invoke-RestMethod tests" -Tags "Feature" {
$response.Content.Method | Should -Be $redirectedMethod
}
It "Validates Invoke-RestMethod handles responses without Location header for requests with Authorization header and redirect: <redirectType>" -TestCases $redirectTests {
param($redirectType, $redirectedMethod)
# Skip relative test as it is not a valid response type.
if ($redirectType -eq 'relative') { return }
# When an Authorization request header is present,
# and -PreserveAuthorizationOnRedirect is not present,
# PowerShell should throw an HTTP Response Exception
# for a redirect response which does not contain a Location response header.
# The correct redirect status code should be included in the exception.
$StatusCode = [int][System.Net.HttpStatusCode]$redirectType
$uri = Get-WebListenerUrl -Test Response -Query @{statuscode = $StatusCode}
$command = "Invoke-RestMethod -Uri '$uri' -Headers @{Authorization = 'foo'}"
$response = ExecuteWebCommand -command $command
$response.Error.Exception | Should -BeOfType 'Microsoft.PowerShell.Commands.HttpResponseException'
$response.Error.Exception.Response.StatusCode | Should -Be $StatusCode
$response.Error.Exception.Response.Headers.Location | Should -BeNullOrEmpty
}
#endregion Redirect tests
Context "Invoke-RestMethod SkipHeaderVerification Tests" {