Files
nexus/backend/Security/BrowserRequestOriginGuard.cs
T
AzuTear cd8c78d165
CI - Build & Test / Backend (.NET) (push) Successful in 45s
CI - Build & Test / Backend integration (PostgreSQL/Toxiproxy) (push) Failing after 1m0s
CI - Build & Test / Frontend (Vue/TS) (push) Successful in 2m49s
CI - Build & Test / Security Check (push) Successful in 7s
CI - Build & Test / Deploy Nexus (push) Has been skipped
feat(stability): unify readiness and recovery
2026-08-01 01:21:33 +02:00

38 lines
1.5 KiB
C#

namespace Nexus.Api.Security;
/// <summary>
/// Rejects browser requests that explicitly identify themselves as cross-site.
/// Requests without browser provenance headers remain valid for trusted API
/// clients; they still need the normal cookie, authentication and rate limits.
/// </summary>
public static class BrowserRequestOriginGuard
{
public static bool IsAllowed(HttpRequest request)
{
var fetchSite = request.Headers["Sec-Fetch-Site"].ToString().Trim();
if (string.Equals(fetchSite, "cross-site", StringComparison.OrdinalIgnoreCase))
return false;
var originValue = request.Headers.Origin.ToString().Trim();
if (originValue.Length == 0)
return true;
if (!Uri.TryCreate(originValue, UriKind.Absolute, out var origin))
return false;
var requestHost = request.Host.Host;
if (requestHost.Length == 0)
return false;
var originPort = origin.IsDefaultPort ? DefaultPort(origin.Scheme) : origin.Port;
var requestPort = request.Host.Port ?? DefaultPort(request.Scheme);
return string.Equals(origin.Scheme, request.Scheme, StringComparison.OrdinalIgnoreCase)
&& string.Equals(origin.Host, requestHost, StringComparison.OrdinalIgnoreCase)
&& originPort == requestPort;
}
private static int DefaultPort(string scheme)
=> string.Equals(scheme, Uri.UriSchemeHttps, StringComparison.OrdinalIgnoreCase) ? 443 : 80;
}