Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

handle bad form data on token (and other) endpoints #958

Merged
merged 1 commit into from
Jul 12, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
using Microsoft.Extensions.Logging;
using Duende.IdentityServer.Events;
using IdentityModel;
using System.IO;

namespace Duende.IdentityServer.Endpoints;

Expand Down Expand Up @@ -54,7 +55,15 @@ public async Task<IEndpointResult> 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<IEndpointResult> ProcessAuthenticationRequestAsync(HttpContext context)
Expand Down
11 changes: 10 additions & 1 deletion src/IdentityServer/Endpoints/DeviceAuthorizationEndpoint.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
using Duende.IdentityServer.Extensions;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
using System.IO;

namespace Duende.IdentityServer.Endpoints;

Expand Down Expand Up @@ -65,7 +66,15 @@ public async Task<IEndpointResult> 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<IEndpointResult> ProcessDeviceAuthorizationRequestAsync(HttpContext context)
Expand Down
19 changes: 18 additions & 1 deletion src/IdentityServer/Endpoints/EndSessionEndpoint.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
using Duende.IdentityServer.Extensions;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
using System.IO;

namespace Duende.IdentityServer.Endpoints;

Expand All @@ -35,7 +36,23 @@ public EndSessionEndpoint(
public async Task<IEndpointResult> 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<IEndpointResult> ProcessEndSessionAsync(HttpContext context)
{
using var activity = Tracing.BasicActivitySource.StartActivity(Constants.EndpointNames.EndSession + "Endpoint");

NameValueCollection parameters;
if (HttpMethods.IsGet(context.Request.Method))
{
Expand Down
11 changes: 10 additions & 1 deletion src/IdentityServer/Endpoints/IntrospectionEndpoint.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
using Duende.IdentityServer.Services;
using Duende.IdentityServer.Validation;
using Duende.IdentityServer.Extensions;
using System.IO;

namespace Duende.IdentityServer.Endpoints;

Expand Down Expand Up @@ -74,7 +75,15 @@ public async Task<IEndpointResult> 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<IEndpointResult> ProcessIntrospectionRequestAsync(HttpContext context)
Expand Down
12 changes: 11 additions & 1 deletion src/IdentityServer/Endpoints/TokenEndpoint.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -69,7 +71,15 @@ public async Task<IEndpointResult> 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<IEndpointResult> ProcessTokenRequestAsync(HttpContext context)
Expand Down
15 changes: 11 additions & 4 deletions src/IdentityServer/Endpoints/TokenRevocationEndpoint.cs
Original file line number Diff line number Diff line change
@@ -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.


Expand All @@ -14,6 +14,7 @@
using Duende.IdentityServer.Validation;
using Microsoft.AspNetCore.Http;
using Duende.IdentityServer.Extensions;
using System.IO;

namespace Duende.IdentityServer.Endpoints;

Expand Down Expand Up @@ -74,9 +75,15 @@ public async Task<IEndpointResult> 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<IEndpointResult> ProcessRevocationRequestAsync(HttpContext context)
Expand Down
Original file line number Diff line number Diff line change
@@ -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.


Expand All @@ -13,6 +13,7 @@
using Duende.IdentityServer.Test;
using IntegrationTests.Common;
using Xunit;
using System.Text;

namespace IntegrationTests.Endpoints.Token;

Expand Down Expand Up @@ -118,4 +119,20 @@ public async Task resource_owner_request_with_funny_headers_should_not_hang()
var result = JsonSerializer.Deserialize<Dictionary<string, JsonElement>>(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<Dictionary<string, JsonElement>>(json);
var error = result["error"].GetString();
error.Should().Be("invalid_request");
}
}