Skip to content

Commit

Permalink
Update form content check to reject multipart forms (IdentityServer#4502
Browse files Browse the repository at this point in the history
)

* add extension method

* switch to new extension method
  • Loading branch information
leastprivilege authored Jun 11, 2020
1 parent f0cbdcc commit eb75047
Show file tree
Hide file tree
Showing 10 changed files with 25 additions and 9 deletions.
2 changes: 1 addition & 1 deletion src/IdentityServer4/src/Endpoints/AuthorizeEndpoint.cs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ public override async Task<IEndpointResult> ProcessAsync(HttpContext context)
}
else if (HttpMethods.IsPost(context.Request.Method))
{
if (!context.Request.HasFormContentType)
if (!context.Request.HasApplicationFormContentType())
{
return new StatusCodeResult(HttpStatusCode.UnsupportedMediaType);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ public async Task<IEndpointResult> ProcessAsync(HttpContext context)
_logger.LogTrace("Processing device authorize request.");

// validate HTTP
if (!HttpMethods.IsPost(context.Request.Method) || !context.Request.HasFormContentType)
if (!HttpMethods.IsPost(context.Request.Method) || !context.Request.HasApplicationFormContentType())
{
_logger.LogWarning("Invalid HTTP request for device authorize endpoint");
return Error(OidcConstants.TokenErrors.InvalidRequest);
Expand Down
2 changes: 1 addition & 1 deletion src/IdentityServer4/src/Endpoints/IntrospectionEndpoint.cs
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ public async Task<IEndpointResult> ProcessAsync(HttpContext context)
return new StatusCodeResult(HttpStatusCode.MethodNotAllowed);
}

if (!context.Request.HasFormContentType)
if (!context.Request.HasApplicationFormContentType())
{
_logger.LogWarning("Invalid media type for introspection endpoint");
return new StatusCodeResult(HttpStatusCode.UnsupportedMediaType);
Expand Down
2 changes: 1 addition & 1 deletion src/IdentityServer4/src/Endpoints/TokenEndpoint.cs
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ public async Task<IEndpointResult> ProcessAsync(HttpContext context)
_logger.LogTrace("Processing token request.");

// validate HTTP
if (!HttpMethods.IsPost(context.Request.Method) || !context.Request.HasFormContentType)
if (!HttpMethods.IsPost(context.Request.Method) || !context.Request.HasApplicationFormContentType())
{
_logger.LogWarning("Invalid HTTP request for token endpoint");
return Error(OidcConstants.TokenErrors.InvalidRequest);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ public async Task<IEndpointResult> ProcessAsync(HttpContext context)
return new StatusCodeResult(HttpStatusCode.MethodNotAllowed);
}

if (!context.Request.HasFormContentType)
if (!context.Request.HasApplicationFormContentType())
{
_logger.LogWarning("Invalid media type");
return new StatusCodeResult(HttpStatusCode.UnsupportedMediaType);
Expand Down
15 changes: 15 additions & 0 deletions src/IdentityServer4/src/Extensions/HttpRequestExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@
// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.


using System;
using Microsoft.AspNetCore.Http;
using System.Linq;
using Microsoft.Net.Http.Headers;

#pragma warning disable 1591

Expand All @@ -26,5 +28,18 @@ public static string GetCorsOrigin(this HttpRequest request)

return null;
}

internal static bool HasApplicationFormContentType(this HttpRequest request)
{
if (request.ContentType is null) return false;

if (MediaTypeHeaderValue.TryParse(request.ContentType, out var header))
{
// Content-Type: application/x-www-form-urlencoded; charset=utf-8
return header.MediaType.Equals("application/x-www-form-urlencoded", StringComparison.OrdinalIgnoreCase);
}

return false;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ public async Task<BearerTokenUsageValidationResult> ValidateAsync(HttpContext co
return result;
}

if (context.Request.HasFormContentType)
if (context.Request.HasApplicationFormContentType())
{
result = await ValidatePostBodyAsync(context);
if (result.TokenFound)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ public async Task<ParsedSecret> ParseAsync(HttpContext context)
{
_logger.LogDebug("Start parsing for JWT client assertion in post body");

if (!context.Request.HasFormContentType)
if (!context.Request.HasApplicationFormContentType())
{
_logger.LogDebug("Content type is not a form");
return null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using System.Linq;
using System.Threading.Tasks;
using IdentityServer4.Configuration;
using IdentityServer4.Extensions;
using IdentityServer4.Models;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
Expand Down Expand Up @@ -44,7 +45,7 @@ public async Task<ParsedSecret> ParseAsync(HttpContext context)
{
_logger.LogDebug("Start parsing for client id in post body");

if (!context.Request.HasFormContentType)
if (!context.Request.HasApplicationFormContentType())
{
_logger.LogDebug("Content type is not a form");
return null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ public async Task<ParsedSecret> ParseAsync(HttpContext context)
{
_logger.LogDebug("Start parsing for secret in post body");

if (!context.Request.HasFormContentType)
if (!context.Request.HasApplicationFormContentType())
{
_logger.LogDebug("Content type is not a form");
return null;
Expand Down

0 comments on commit eb75047

Please sign in to comment.