feat(stability): unify readiness and recovery
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
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
This commit is contained in:
@@ -0,0 +1,37 @@
|
||||
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;
|
||||
}
|
||||
Reference in New Issue
Block a user