diff --git a/CHANGELOG.md b/CHANGELOG.md index 7e202b4e15..93b4ca76ae 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -23,6 +23,7 @@ - Fix DI issue by binding to MAUI using lifecycle events ([#2006](https://github.com/getsentry/sentry-dotnet/pull/2006)) - Unhide `SentryEvent.Exception` ([#2011](https://github.com/getsentry/sentry-dotnet/pull/2011)) - Bump `Google.Cloud.Functions.Hosting` to version 1.1.0 ([#2015](https://github.com/getsentry/sentry-dotnet/pull/2015)) +- Fix default host issue for the Sentry Tunnel middleware ([#2019](https://github.com/getsentry/sentry-dotnet/pull/2019)) ## 3.22.0 diff --git a/src/Sentry.AspNetCore/SentryTunnelMiddleware.cs b/src/Sentry.AspNetCore/SentryTunnelMiddleware.cs index 829a803b17..2e7c63b855 100644 --- a/src/Sentry.AspNetCore/SentryTunnelMiddleware.cs +++ b/src/Sentry.AspNetCore/SentryTunnelMiddleware.cs @@ -22,7 +22,7 @@ public class SentryTunnelMiddleware : IMiddleware /// public SentryTunnelMiddleware(string[] allowedHosts) { - _allowedHosts = new[] { "sentry.io" }.Concat(allowedHosts).ToArray(); + _allowedHosts = allowedHosts; } /// @@ -77,7 +77,10 @@ public async Task InvokeAsync(HttpContext context, RequestDelegate next) await response.WriteAsync("Invalid DSN JSON supplied").ConfigureAwait(false); return; } - if (headerJson.TryGetValue("dsn", out var dsnString) && Uri.TryCreate(dsnString.ToString(), UriKind.Absolute, out var dsn) && _allowedHosts.Contains(dsn.Host)) + + if (headerJson.TryGetValue("dsn", out var dsnString) && + Uri.TryCreate(dsnString.ToString(), UriKind.Absolute, out var dsn) && + IsHostAllowed(dsn.Host)) { var projectId = dsn.AbsolutePath.Trim('/'); memoryStream.Position = 0; @@ -110,4 +113,9 @@ public async Task InvokeAsync(HttpContext context, RequestDelegate next) await response.WriteAsync("Received empty body").ConfigureAwait(false); } } + + private bool IsHostAllowed(string host) => + host.EndsWith(".sentry.io", StringComparison.OrdinalIgnoreCase) || + host.Equals("sentry.io", StringComparison.OrdinalIgnoreCase) || + _allowedHosts.Contains(host, StringComparer.OrdinalIgnoreCase); } diff --git a/src/Sentry.AspNetCore/SentryWebHostBuilderExtensions.cs b/src/Sentry.AspNetCore/SentryWebHostBuilderExtensions.cs index f9c0cee4ee..03ec7f5067 100644 --- a/src/Sentry.AspNetCore/SentryWebHostBuilderExtensions.cs +++ b/src/Sentry.AspNetCore/SentryWebHostBuilderExtensions.cs @@ -110,8 +110,12 @@ public static IWebHostBuilder UseSentry( /// /// Adds and configures the Sentry tunneling middleware. /// - /// - /// The extra hostnames to be allowed for the tunneling. sentry.io is allowed by default; add your own Sentry domain if you use a self-hosted Sentry or Relay. + /// The service collection + /// + /// The extra hostnames to be allowed for the tunneling. + /// Hosts ending in .sentry.io are always allowed, and do not need to be included in this list. + /// Add your own domain if you use a self-hosted Sentry or Relay. + /// public static void AddSentryTunneling(this IServiceCollection services, params string[] hostnames) => services.AddScoped(_ => new SentryTunnelMiddleware(hostnames)); diff --git a/test/Sentry.AspNetCore.Tests/Tunnel/IntegrationsTests.cs b/test/Sentry.AspNetCore.Tests/Tunnel/IntegrationsTests.cs index 08c09859bb..9b1afcd1c3 100644 --- a/test/Sentry.AspNetCore.Tests/Tunnel/IntegrationsTests.cs +++ b/test/Sentry.AspNetCore.Tests/Tunnel/IntegrationsTests.cs @@ -28,13 +28,16 @@ public IntegrationsTests() _server = new TestServer(builder); } - [Fact] - public async Task TunnelMiddleware_CanForwardValidEnvelope() + [Theory] + [InlineData("sentry.io")] + [InlineData("ingest.sentry.io")] + [InlineData("o12345.ingest.sentry.io")] + public async Task TunnelMiddleware_CanForwardValidEnvelope(string host) { var requestMessage = new HttpRequestMessage(new HttpMethod("POST"), "/tunnel") { Content = new StringContent( - @"{""sent_at"":""2021-01-01T00:00:00.000Z"",""sdk"":{""name"":""sentry.javascript.browser"",""version"":""6.8.0""},""dsn"":""https://dns@sentry.io/1""} + @"{""sent_at"":""2021-01-01T00:00:00.000Z"",""sdk"":{""name"":""sentry.javascript.browser"",""version"":""6.8.0""},""dsn"":""https://dns@" + host + @"/1""} {""type"":""session""} {""sid"":""fda00e933162466c849962eaea0cfaff""}") };