DBSC registration returns 500 instead of 400 for a proof with invalid UTF-8 in the jwk
- Dominant language
- C#
- Stars
- 38.4k
- Forks
- 10.9k
- Avg merge
- 2d 6h
- Merged PRs (30d)
- 290
Description
### Is there an existing issue for this?
- [x] I have searched the existing issues
### Describe the bug
The DBSC registration endpoint (`POST /.well-known/dbsc/registration`) answers a crafted registration proof with an unhandled `System.InvalidOperationException` -- surfaced as **HTTP 500** -- where a rejected proof is meant to produce **400**.
### Expected Behavior
In such case `400 Bad request` should be returned as a result for the api call.
### Steps To Reproduce
```csharp
using Microsoft.AspNetCore.Authentication.Cookies;
var builder = WebApplication.CreateBuilder(args);
builder.Logging.ClearProviders();
builder.WebHost.UseUrls("http://127.0.0.1:5199");
builder.Services
.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
.AddCookie()
.AddDeviceBoundSession(CookieAuthenticationDefaults.AuthenticationScheme);
var app = builder.Build();
app.UseAuthentication();
app.MapGet("/", () => "ok");
await app.RunAsync();
```
Prepare and call the API with invalid and invalid utf-8 byte in jwt
```csharp
static string B64Url(byte[] b) => Convert.ToBase64String(b).TrimEnd('=').Replace('+', '-').Replace('/', '_');
byte[] header =
[
.. "{\"alg\":\"ES256\",\"typ\":\"dbsc+jwt\",\"jwk\":{\"kty\":\"EC\",\"crv\":\"P-256\",\"x\":\""u8,
0xA6,
.. "\"}}"u8,
];
string proof = $"{B64Url(header)}.{B64Url("{}"u8.ToArray())}.{B64Url(new byte[64])}";
using var http = new HttpClient();
async Task Post(HttpClient client, string label, string headerValue)
{
var req = new HttpRequestMessage(HttpMethod.Post, "http://127.0.0.1:5199/.well-known/dbsc/registration");
req.Headers.TryAddWithoutValidation("Secure-Session-Response", headerValue);
try
{
var resp = await client.SendAsync(req);
Console.WriteLine($"{label,-22} -> HTTP {(int)resp.StatusCode} {resp.StatusCode}");
}
catch (Exception ex)
{
Console.WriteLine($"{label,-22} -> transport failure: {ex.GetType().Name}: {ex.Message}");
}
}
await Post(http, "garbage proof", "not-a-jwt"); // 400 Bad Request
await Post(http, "malformed-utf8 jwk", proof); // 500 Internal server error
```
### Exceptions (if any)
Internally the `ValidateAsync` throws `System.InvalidOperationException: Cannot transcode invalid UTF-8 JSON text to UTF-16 string.`. Because it is not guarded with try-catch and throws, null is not returned in such case and later it's not converted to 400 Bad request by the handler.
### .NET Version
.NET 11.0.0-rc.1.26425.128
### Anything else?
Tested against Microsoft.AspNetCore.Authentication.DeviceBoundSessions 0.11.0-rc.1.26425.128.
Contributor guide
Assessment
This issue has not been assessed yet.