Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions src/Core/Utilities/CoreHelpers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -644,6 +644,16 @@ public static string GetApplicationCacheServiceBusSubscriptionName(GlobalSetting
{
return realConnectingIp.ToString();
}
else if (globalSettings.SelfHosted && httpContext.Request.Headers.TryGetValue("X-Forwarded-For", out var xForwardedFor))
{
// X-Forwarded-For is a de-facto standard
// RFC7239 normalizes into the Forwarded header (https://datatracker.ietf.org/doc/rfc7239/)
// it may replace the X-Forwarded-For header in the future
// Using a library should be more convenient to take benefit of both format and future evolutions
//
// Security: Considering here that Nginx has sanitized the header and there is no value forged from outside
return xForwardedFor.ToString().Split(",")[0];
}

return httpContext.Connection?.RemoteIpAddress?.ToString();
}
Expand Down
34 changes: 34 additions & 0 deletions test/Core.Test/Context/CurrentContextTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,40 @@ public async Task BuildAsync_HttpContext_SetsDeviceType(
Assert.Equal(deviceType, sutProvider.Sut.DeviceType);
}

[Theory, BitAutoData]
public async Task BuildAsync_HttpContext_TestXConnectingIP(
SutProvider<CurrentContext> sutProvider)
{
var httpContext = new DefaultHttpContext();
var globalSettings = new Core.Settings.GlobalSettings();
// Arrange
globalSettings.SelfHosted = false;
httpContext.Request.Headers["X-Connecting-IP"] = "10.11.12.13";

// Act
await sutProvider.Sut.BuildAsync(httpContext, globalSettings);

// Assert
Assert.Equal("10.11.12.13", sutProvider.Sut.IpAddress);
}

[Theory, BitAutoData]
public async Task BuildAsync_HttpContext_TestXForwardedInSelfHosted(
SutProvider<CurrentContext> sutProvider)
{
var httpContext = new DefaultHttpContext();
var globalSettings = new Core.Settings.GlobalSettings();
// Arrange
globalSettings.SelfHosted = true;
httpContext.Request.Headers["X-Forwarded-For"] = "1.2.3.4,5.6.7.8";

// Act
await sutProvider.Sut.BuildAsync(httpContext, globalSettings);

// Assert
Assert.Equal("1.2.3.4", sutProvider.Sut.IpAddress);
}

[Theory, BitAutoData]
public async Task BuildAsync_HttpContext_SetsCloudflareFlags(
SutProvider<CurrentContext> sutProvider)
Expand Down
Loading