Skip to content

Commit fc19044

Browse files
committed
add trusted proxies
1 parent ff241db commit fc19044

4 files changed

Lines changed: 60 additions & 2 deletions

File tree

code-secure-api/code-secure-api.sln.DotSettings.user

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AIdentityUser_00601_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003FLibrary_003FApplication_0020Support_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F99c3d2e0c73c44a3ba4adfb05dce7a4612000_003F6b_003F8586a419_003FIdentityUser_00601_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
1717
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AIError_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003FLibrary_003FApplication_0020Support_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F96520fd986094506b111be52efa0680bd000_003F48_003F638f4741_003FIError_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
1818
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AInternalRedmineApiWebClient_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003FLibrary_003FApplication_0020Support_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003Fbcb13713decf44c2a04d14c05ebda1c53ec00_003Fa2_003F1beacdf3_003FInternalRedmineApiWebClient_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
19+
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AIPAddress_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003FLibrary_003FApplication_0020Support_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F0a489d3d54014e478fd83ef812b0128b3ca00_003Fd1_003Fe856bf33_003FIPAddress_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
1920
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AIServiceScope_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003FLibrary_003FApplication_0020Support_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F9efc724329ab415f9a4af6b465bba4d621800_003Fa7_003F0967fc6a_003FIServiceScope_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
2021
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AIssue_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003FLibrary_003FApplication_0020Support_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F405cf7b3ac594d93a66a6babf366c2313dc00_003F95_003Fa43ffe07_003FIssue_002Ecs_002Fz_003A2_002D1/@EntryIndexedValue">ForceIncluded</s:String>
2122
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ALoggerExtensions_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003FLibrary_003FApplication_0020Support_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003Faf4d3aff100447d99509a5a8d2ea755f23200_003Fca_003Fb81666be_003FLoggerExtensions_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>

code-secure-api/code-secure-api/Api/ApiServer.cs

Lines changed: 54 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
using System.Net;
2+
using System.Net.Sockets;
13
using System.Text.Json.Serialization;
24
using System.Text.RegularExpressions;
35
using CodeSecure.Application;
@@ -10,6 +12,7 @@
1012
using Microsoft.AspNetCore.Mvc.ApplicationModels;
1113
using Scalar.AspNetCore;
1214
using Serilog;
15+
using IPNetwork = Microsoft.AspNetCore.HttpOverrides.IPNetwork;
1316

1417
namespace CodeSecure.Api;
1518

@@ -20,7 +23,9 @@ public static void Run(string[] args)
2023
var builder = WebApplication.CreateBuilder(args);
2124
builder.Services.Configure<ForwardedHeadersOptions>(options =>
2225
{
23-
options.ForwardedHeaders = ForwardedHeaders.XForwardedProto | ForwardedHeaders.XForwardedHost;
26+
options.ForwardedHeaders = ForwardedHeaders.XForwardedProto | ForwardedHeaders.XForwardedHost |
27+
ForwardedHeaders.XForwardedFor;
28+
options.AddTrustedProxies(Configuration.TrustedProxies);
2429
});
2530
builder.Host.UseSerilog((context, configuration) =>
2631
configuration.ReadFrom.Configuration(context.Configuration));
@@ -89,6 +94,54 @@ public static void Run(string[] args)
8994
app.LoadAuthenticationProviders();
9095
app.Run();
9196
}
97+
98+
private static void AddTrustedProxies(this ForwardedHeadersOptions options, string trustedProxies)
99+
{
100+
if (string.IsNullOrWhiteSpace(trustedProxies))
101+
return;
102+
var proxies = trustedProxies.Split(',', StringSplitOptions.RemoveEmptyEntries);
103+
104+
foreach (var proxy in proxies)
105+
{
106+
var trimmedProxy = proxy.Trim();
107+
// Check if it's a CIDR block
108+
if (trimmedProxy.Contains('/'))
109+
{
110+
if (TryParseIpNetwork(trimmedProxy, out var network, out var prefixLength))
111+
{
112+
options.KnownNetworks.Add(new IPNetwork(network, prefixLength));
113+
}
114+
}
115+
// Single IP address
116+
else if (IPAddress.TryParse(trimmedProxy, out var ipAddress))
117+
{
118+
options.KnownProxies.Add(ipAddress);
119+
}
120+
}
121+
}
122+
123+
private static bool TryParseIpNetwork(string cidr, out IPAddress network, out int prefixLength)
124+
{
125+
network = IPAddress.None;
126+
prefixLength = 0;
127+
128+
var parts = cidr.Split('/');
129+
if (parts.Length != 2)
130+
return false;
131+
132+
if (!IPAddress.TryParse(parts[0], out network))
133+
return false;
134+
135+
if (!int.TryParse(parts[1], out prefixLength))
136+
return false;
137+
138+
// Validate prefix length based on address family
139+
var maxPrefixLength = network.AddressFamily == AddressFamily.InterNetwork ? 32 : 128;
140+
if (prefixLength < 0 || prefixLength > maxPrefixLength)
141+
return false;
142+
143+
return true;
144+
}
92145
}
93146

94147
internal sealed partial class SlugifyParameterTransformer : IOutboundParameterTransformer

code-secure-api/code-secure-api/Application/AppConfig.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,9 @@ public class AppConfig
3232

3333
[Option(Env = "FRONTEND_URL", Default = "")]
3434
public string FrontendUrl { get; set; } = string.Empty;
35+
36+
[Option(Env = "TRUSTED_PROXIES", Default = "")]
37+
public string TrustedProxies { get; set; } = string.Empty;
3538

3639
[JsonIgnore] internal SecurityKey AccessTokenSecurityKey = null!;
3740
[JsonIgnore] internal SecurityKey RefreshTokenSecurityKey = null!;

code-secure-api/code-secure-api/Application/Configuration.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,11 @@ public static class Configuration
77
private static readonly AppConfig Config = AppConfig.Load();
88
public const string AppName = "CodeSecure";
99
public static string FrontendUrl => Config.FrontendUrl;
10+
public static string TrustedProxies => Config.TrustedProxies;
1011

1112
public static string DbConnectionString =>
1213
$"Host={Config.DbServer};Database={Config.DbName};Username={Config.DbUsername};Password={Config.DbPassword}";
13-
14+
1415
public static string SystemPassword => Config.SystemPassword;
1516
public static SecurityKey AccessTokenKey => Config.AccessTokenSecurityKey;
1617
public static SecurityKey RefreshTokenKey => Config.RefreshTokenSecurityKey;

0 commit comments

Comments
 (0)