diff --git a/src/IdentityServer/Endpoints/BackchannelAuthenticationEndpoint.cs b/src/IdentityServer/Endpoints/BackchannelAuthenticationEndpoint.cs index 514acea57..2c9553de9 100644 --- a/src/IdentityServer/Endpoints/BackchannelAuthenticationEndpoint.cs +++ b/src/IdentityServer/Endpoints/BackchannelAuthenticationEndpoint.cs @@ -13,6 +13,7 @@ using Microsoft.Extensions.Logging; using Duende.IdentityServer.Events; using IdentityModel; +using System.IO; namespace Duende.IdentityServer.Endpoints; @@ -54,7 +55,15 @@ public async Task ProcessAsync(HttpContext context) return Error(OidcConstants.BackchannelAuthenticationRequestErrors.InvalidRequest); } - return await ProcessAuthenticationRequestAsync(context); + try + { + return await ProcessAuthenticationRequestAsync(context); + } + catch (InvalidDataException ex) + { + _logger.LogWarning(ex, "Invalid HTTP request for backchannel authentication endpoint"); + return Error(OidcConstants.BackchannelAuthenticationRequestErrors.InvalidRequest); + } } private async Task ProcessAuthenticationRequestAsync(HttpContext context) diff --git a/src/IdentityServer/Endpoints/DeviceAuthorizationEndpoint.cs b/src/IdentityServer/Endpoints/DeviceAuthorizationEndpoint.cs index ac5caec39..3ea90fb16 100644 --- a/src/IdentityServer/Endpoints/DeviceAuthorizationEndpoint.cs +++ b/src/IdentityServer/Endpoints/DeviceAuthorizationEndpoint.cs @@ -14,6 +14,7 @@ using Duende.IdentityServer.Extensions; using Microsoft.AspNetCore.Http; using Microsoft.Extensions.Logging; +using System.IO; namespace Duende.IdentityServer.Endpoints; @@ -65,7 +66,15 @@ public async Task ProcessAsync(HttpContext context) return Error(OidcConstants.TokenErrors.InvalidRequest); } - return await ProcessDeviceAuthorizationRequestAsync(context); + try + { + return await ProcessDeviceAuthorizationRequestAsync(context); + } + catch (InvalidDataException ex) + { + _logger.LogWarning(ex, "Invalid HTTP request for device endpoint"); + return Error(OidcConstants.TokenErrors.InvalidRequest); + } } private async Task ProcessDeviceAuthorizationRequestAsync(HttpContext context) diff --git a/src/IdentityServer/Endpoints/EndSessionEndpoint.cs b/src/IdentityServer/Endpoints/EndSessionEndpoint.cs index b2166c852..cff126580 100644 --- a/src/IdentityServer/Endpoints/EndSessionEndpoint.cs +++ b/src/IdentityServer/Endpoints/EndSessionEndpoint.cs @@ -11,6 +11,7 @@ using Duende.IdentityServer.Extensions; using Microsoft.AspNetCore.Http; using Microsoft.Extensions.Logging; +using System.IO; namespace Duende.IdentityServer.Endpoints; @@ -35,7 +36,23 @@ public EndSessionEndpoint( public async Task ProcessAsync(HttpContext context) { using var activity = Tracing.BasicActivitySource.StartActivity(Constants.EndpointNames.EndSession + "Endpoint"); - + + try + { + return await ProcessEndSessionAsync(context); + } + catch (InvalidDataException ex) + { + _logger.LogWarning(ex, "Invalid HTTP request for end session endpoint"); + return new StatusCodeResult(HttpStatusCode.BadRequest); + } + } + + + async Task ProcessEndSessionAsync(HttpContext context) + { + using var activity = Tracing.BasicActivitySource.StartActivity(Constants.EndpointNames.EndSession + "Endpoint"); + NameValueCollection parameters; if (HttpMethods.IsGet(context.Request.Method)) { diff --git a/src/IdentityServer/Endpoints/IntrospectionEndpoint.cs b/src/IdentityServer/Endpoints/IntrospectionEndpoint.cs index 20cc1d9b5..495a89663 100644 --- a/src/IdentityServer/Endpoints/IntrospectionEndpoint.cs +++ b/src/IdentityServer/Endpoints/IntrospectionEndpoint.cs @@ -13,6 +13,7 @@ using Duende.IdentityServer.Services; using Duende.IdentityServer.Validation; using Duende.IdentityServer.Extensions; +using System.IO; namespace Duende.IdentityServer.Endpoints; @@ -74,7 +75,15 @@ public async Task ProcessAsync(HttpContext context) return new StatusCodeResult(HttpStatusCode.UnsupportedMediaType); } - return await ProcessIntrospectionRequestAsync(context); + try + { + return await ProcessIntrospectionRequestAsync(context); + } + catch (InvalidDataException ex) + { + _logger.LogWarning(ex, "Invalid HTTP request for introspection endpoint"); + return new StatusCodeResult(HttpStatusCode.BadRequest); + } } private async Task ProcessIntrospectionRequestAsync(HttpContext context) diff --git a/src/IdentityServer/Endpoints/TokenEndpoint.cs b/src/IdentityServer/Endpoints/TokenEndpoint.cs index e24457a6e..bb63fe1d4 100644 --- a/src/IdentityServer/Endpoints/TokenEndpoint.cs +++ b/src/IdentityServer/Endpoints/TokenEndpoint.cs @@ -14,6 +14,8 @@ using Duende.IdentityServer.ResponseHandling; using Duende.IdentityServer.Services; using Duende.IdentityServer.Validation; +using System; +using System.IO; namespace Duende.IdentityServer.Endpoints; @@ -69,7 +71,15 @@ public async Task ProcessAsync(HttpContext context) return Error(OidcConstants.TokenErrors.InvalidRequest); } - return await ProcessTokenRequestAsync(context); + try + { + return await ProcessTokenRequestAsync(context); + } + catch(InvalidDataException ex) + { + _logger.LogWarning(ex, "Invalid HTTP request for token endpoint"); + return Error(OidcConstants.TokenErrors.InvalidRequest); + } } private async Task ProcessTokenRequestAsync(HttpContext context) diff --git a/src/IdentityServer/Endpoints/TokenRevocationEndpoint.cs b/src/IdentityServer/Endpoints/TokenRevocationEndpoint.cs index c28c22672..4bcea28c4 100644 --- a/src/IdentityServer/Endpoints/TokenRevocationEndpoint.cs +++ b/src/IdentityServer/Endpoints/TokenRevocationEndpoint.cs @@ -1,4 +1,4 @@ -// Copyright (c) Duende Software. All rights reserved. +// Copyright (c) Duende Software. All rights reserved. // See LICENSE in the project root for license information. @@ -14,6 +14,7 @@ using Duende.IdentityServer.Validation; using Microsoft.AspNetCore.Http; using Duende.IdentityServer.Extensions; +using System.IO; namespace Duende.IdentityServer.Endpoints; @@ -74,9 +75,15 @@ public async Task ProcessAsync(HttpContext context) return new StatusCodeResult(HttpStatusCode.UnsupportedMediaType); } - var response = await ProcessRevocationRequestAsync(context); - - return response; + try + { + return await ProcessRevocationRequestAsync(context); + } + catch (InvalidDataException ex) + { + _logger.LogWarning(ex, "Invalid HTTP request for revocation endpoint"); + return new StatusCodeResult(HttpStatusCode.BadRequest); + } } private async Task ProcessRevocationRequestAsync(HttpContext context) diff --git a/test/IdentityServer.IntegrationTests/Endpoints/Token/TokenEndpointTests.cs b/test/IdentityServer.IntegrationTests/Endpoints/Token/TokenEndpointTests.cs index e6a3a8ebd..1c8cb8423 100644 --- a/test/IdentityServer.IntegrationTests/Endpoints/Token/TokenEndpointTests.cs +++ b/test/IdentityServer.IntegrationTests/Endpoints/Token/TokenEndpointTests.cs @@ -1,4 +1,4 @@ -// Copyright (c) Duende Software. All rights reserved. +// Copyright (c) Duende Software. All rights reserved. // See LICENSE in the project root for license information. @@ -13,6 +13,7 @@ using Duende.IdentityServer.Test; using IntegrationTests.Common; using Xunit; +using System.Text; namespace IntegrationTests.Endpoints.Token; @@ -118,4 +119,20 @@ public async Task resource_owner_request_with_funny_headers_should_not_hang() var result = JsonSerializer.Deserialize>(json); result.ContainsKey("error").Should().BeFalse(); } + + [Fact] + [Trait("Category", Category)] + public async Task invalid_form_post_text_values_should_return_400_error() + { + var text = $"grant_type=client_credentials&client_id={client_id}&client_secret={client_secret}&scope=%00"; + var content = new StringContent(text, Encoding.UTF8, "application/x-www-form-urlencoded"); + + var response = await _mockPipeline.BackChannelClient.PostAsync(IdentityServerPipeline.TokenEndpoint, content); + + response.StatusCode.Should().Be(HttpStatusCode.BadRequest); + var json = await response.Content.ReadAsStringAsync(); + var result = JsonSerializer.Deserialize>(json); + var error = result["error"].GetString(); + error.Should().Be("invalid_request"); + } } \ No newline at end of file