Skip to content

Commit 24e837b

Browse files
authored
Merge pull request #4 from securenative/dev
Support pii data remove from config
2 parents 96df344 + 941771f commit 24e837b

File tree

7 files changed

+350
-29
lines changed

7 files changed

+350
-29
lines changed

README.md

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,3 +195,72 @@ public void WebhookEndpoint()
195195
var isVerified = securenative.VerifyRequestPayload(Request);
196196
}
197197
```
198+
199+
## Extract proxy headers from cloud providers
200+
201+
You can specify custom header keys to allow extraction of client ip from different providers.
202+
This example demonstrates the usage of proxy headers for ip extraction from Cloudflare.
203+
204+
### Option 1: Using config file
205+
```json
206+
{
207+
"SECURENATIVE_API_KEY": "YOUR_API_KEY",
208+
"SECURENATIVE_PROXY_HEADERS": ["CF-Connecting-IP"]
209+
}
210+
```
211+
212+
Initialize sdk as shown above.
213+
214+
### Options 2: Using ConfigurationBuilder
215+
216+
```dotenv
217+
using SecureNative.SDK;
218+
219+
220+
SecureNativeOptions Options = ConfigurationManager.ConfigBuilder()
221+
.WithApiKey("API_KEY"))
222+
.WithProxyHeaders(new ["CF-Connecting-IP"])
223+
.Build());
224+
225+
var securenative = Client.Init(Options);
226+
```
227+
228+
```go
229+
options := config.DefaultSecureNativeOptions()
230+
options.ApiKey = "YOUR_API_KEY"
231+
options.ProxyHeaders = []string{"CF-Connecting-IP"}
232+
233+
sn, err := sdk.InitSDK(options)
234+
if err != nil {
235+
log.Fatal("Do some error handling")
236+
}
237+
```
238+
239+
## Remove PII Data From Headers
240+
241+
By default, SecureNative SDK remove any known pii headers from the received request.
242+
We also support using custom pii headers and regex matching via configuration, for example:
243+
244+
### Option 1: Using config file
245+
```json
246+
{
247+
"SECURENATIVE_API_KEY": "YOUR_API_KEY",
248+
"SECURENATIVE_PII_HEADERS": ["apiKey"]
249+
}
250+
```
251+
252+
Initialize sdk as shown above.
253+
254+
### Options 2: Using ConfigurationBuilder
255+
256+
```dotenv
257+
using SecureNative.SDK;
258+
259+
260+
SecureNativeOptions Options = ConfigurationManager.ConfigBuilder()
261+
.WithApiKey("API_KEY"))
262+
.WithPiiRegexPattern(@"((?i)(http_auth_)(\w+)?)")
263+
.Build());
264+
265+
var securenative = Client.Init(Options);
266+
```

SecureNative.SDK/Config/SecureNativeConfigurationBuilder.cs

Lines changed: 27 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -14,20 +14,24 @@ public class SecureNativeConfigurationBuilder
1414
private string LogLevel { get; set; }
1515
private string FailOverStrategy { get; set; }
1616
private string[] ProxyHeaders { get; set; }
17+
private string[] PiiHeaders { get; set; }
18+
private string PiiRegexPattern { get; set; }
1719

1820
public static SecureNativeConfigurationBuilder DefaultConfigBuilder()
1921
{
2022
return new SecureNativeConfigurationBuilder()
21-
.WithApiKey("")
22-
.WithApiUrl("https://api.securenative.com/collector/api/v1")
23-
.WithInterval(1000)
24-
.WithTimeout(1500)
25-
.WithMaxEvents(1000)
26-
.WithAutoSend(true)
27-
.WithDisable(false)
28-
.WithLogLevel("fatal")
29-
.WithFailOverStrategy(Enums.FailOverStrategy.FAIL_OPEN)
30-
.WithProxyHeaders(new string[]{});
23+
.WithApiKey("")
24+
.WithApiUrl("https://api.securenative.com/collector/api/v1")
25+
.WithInterval(1000)
26+
.WithTimeout(1500)
27+
.WithMaxEvents(1000)
28+
.WithAutoSend(true)
29+
.WithDisable(false)
30+
.WithLogLevel("fatal")
31+
.WithFailOverStrategy(Enums.FailOverStrategy.FAIL_OPEN)
32+
.WithProxyHeaders(new string[] { })
33+
.WithPiiHeaders(new string[] { })
34+
.WithPiiRegexPattern("");
3135
}
3236

3337
public SecureNativeConfigurationBuilder WithApiKey(string apiKey)
@@ -90,9 +94,21 @@ public SecureNativeConfigurationBuilder WithProxyHeaders(string[] proxyHeaders)
9094
return this;
9195
}
9296

97+
public SecureNativeConfigurationBuilder WithPiiHeaders(string[] piiHeaders)
98+
{
99+
PiiHeaders = piiHeaders;
100+
return this;
101+
}
102+
103+
public SecureNativeConfigurationBuilder WithPiiRegexPattern(string piiRegexPattern)
104+
{
105+
PiiRegexPattern = piiRegexPattern;
106+
return this;
107+
}
108+
93109
public SecureNativeOptions Build()
94110
{
95-
return new SecureNativeOptions(ApiKey, ApiUrl, Interval, MaxEvents, Timeout, AutoSend, Disable, LogLevel, FailOverStrategy, ProxyHeaders);
111+
return new SecureNativeOptions(ApiKey, ApiUrl, Interval, MaxEvents, Timeout, AutoSend, Disable, LogLevel, FailOverStrategy, ProxyHeaders, PiiHeaders, PiiRegexPattern);
96112
}
97113
}
98114
}

SecureNative.SDK/Config/SecureNativeOptions.cs

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,10 @@ public class SecureNativeOptions
1212
private string LogLevel { get; set; }
1313
private string FailOverStrategy { get; set; }
1414
private string[] ProxyHeaders { get; set; }
15+
private string[] PiiHeaders { get; set; }
16+
private string PiiRegexPattern { get; set; }
1517

16-
public SecureNativeOptions(string apiKey, string apiUrl, int interval, int maxEvents, int timeout, bool autoSend, bool disable, string logLevel, string failOverStrategy, string[] proxyHeaders)
18+
public SecureNativeOptions(string apiKey, string apiUrl, int interval, int maxEvents, int timeout, bool autoSend, bool disable, string logLevel, string failOverStrategy, string[] proxyHeaders, string[] piiHeaders, string piiRegexPattern)
1719
{
1820
ApiKey = apiKey;
1921
ApiUrl = apiUrl;
@@ -25,6 +27,8 @@ public SecureNativeOptions(string apiKey, string apiUrl, int interval, int maxEv
2527
LogLevel = logLevel;
2628
FailOverStrategy = failOverStrategy;
2729
ProxyHeaders = proxyHeaders;
30+
PiiHeaders = piiHeaders;
31+
PiiRegexPattern = piiRegexPattern;
2832
}
2933

3034
public string GetApiKey()
@@ -126,5 +130,25 @@ public void SetProxyHeaders(string[] value)
126130
{
127131
ProxyHeaders = value;
128132
}
133+
134+
public string[] GetPiiHeaders()
135+
{
136+
return PiiHeaders;
137+
}
138+
139+
public void SetPiiHeaders(string[] value)
140+
{
141+
PiiHeaders = value;
142+
}
143+
144+
public string GetPiiRegexPattern()
145+
{
146+
return PiiRegexPattern;
147+
}
148+
149+
public void SetPiiRegexPattern(string value)
150+
{
151+
PiiRegexPattern = value;
152+
}
129153
}
130154
}

SecureNative.SDK/Context/SecureNativeContextBuilder.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ public SecureNativeContextBuilder WithClientToken(string clientToken)
5959

6060
public static SecureNativeContextBuilder FromHttpRequest(HttpRequest request, SecureNativeOptions options)
6161
{
62-
var headers = RequestUtils.GetHeadersFromRequest(request);
62+
var headers = RequestUtils.GetHeadersFromRequest(request, options);
6363

6464
var clientToken = RequestUtils.GetCookieValueFromRequest(request, RequestUtils.SecurenativeCookie);
6565
if (string.IsNullOrEmpty(clientToken))
@@ -79,7 +79,7 @@ public static SecureNativeContextBuilder FromHttpRequest(HttpRequest request, Se
7979

8080
public static SecureNativeContextBuilder FromHttpRequest(HttpWebRequest request, SecureNativeOptions options)
8181
{
82-
var headers = RequestUtils.GetHeadersFromRequest(request);
82+
var headers = RequestUtils.GetHeadersFromRequest(request, options);
8383

8484
var clientToken = RequestUtils.GetCookieValueFromRequest(request, RequestUtils.SecurenativeCookie);
8585
if (string.IsNullOrEmpty(clientToken))

SecureNative.SDK/Utils/RequestUtils.cs

Lines changed: 101 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
using System.Collections.Generic;
33
using System.Linq;
44
using System.Net;
5+
using System.Text.RegularExpressions;
56
using Microsoft.AspNetCore.Http;
67
using SecureNative.SDK.Config;
78

@@ -17,20 +18,65 @@ public static class RequestUtils
1718
"x-forwarded-for", "x-client-ip", "x-real-ip", "x-forwarded", "x-cluster-client-ip", "forwarded-for",
1819
"forwarded", "via"
1920
};
21+
private static readonly List<string> PiiHeaders = new List<string>
22+
{
23+
"authorization", "access_token", "apikey", "password", "passwd", "secret", "api_key"
24+
};
2025

21-
public static Dictionary<string, string> GetHeadersFromRequest(HttpWebRequest request)
26+
public static Dictionary<string, string> GetHeadersFromRequest(HttpWebRequest request, SecureNativeOptions options)
2227
{
2328
var headers = new Dictionary<string, string>();
24-
try
29+
if (options?.GetPiiHeaders().Length > 0)
2530
{
26-
foreach (var key in request.Headers.AllKeys)
31+
try
32+
{
33+
foreach (var key in request.Headers.AllKeys)
34+
{
35+
if (!options.GetPiiHeaders().Contains(key))
36+
{
37+
headers.Add(key, request.Headers[key]);
38+
}
39+
}
40+
}
41+
catch (Exception)
42+
{
43+
// ignored
44+
}
45+
} else if (options != null && options.GetPiiRegexPattern() != "")
46+
{
47+
try
48+
{
49+
var pattern = new Regex(options.GetPiiRegexPattern());
50+
51+
foreach (var key in request.Headers.AllKeys)
52+
{
53+
if (!pattern.Match(key).Success)
54+
{
55+
headers.Add(key, request.Headers[key]);
56+
}
57+
}
58+
}
59+
catch (Exception)
2760
{
28-
headers.Add(key, request.Headers[key]);
61+
// ignored
2962
}
3063
}
31-
catch (Exception)
64+
else
3265
{
33-
// ignored
66+
try
67+
{
68+
foreach (var key in request.Headers.AllKeys)
69+
{
70+
if (!PiiHeaders.Contains(key))
71+
{
72+
headers.Add(key, request.Headers[key]);
73+
}
74+
}
75+
}
76+
catch (Exception)
77+
{
78+
// ignored
79+
}
3480
}
3581

3682
return headers;
@@ -80,7 +126,7 @@ private static string ParseCookie(string cookieString, string cookieName)
80126

81127
public static string GetClientIpFromRequest(HttpWebRequest request, SecureNativeOptions options)
82128
{
83-
if (options?.GetProxyHeaders() != null)
129+
if (options?.GetProxyHeaders().Length > 0)
84130
{
85131
foreach (var header in options.GetProxyHeaders())
86132
{
@@ -140,19 +186,60 @@ public static string GetRemoteIpFromRequest(HttpWebRequest request)
140186
return string.Empty;
141187
}
142188

143-
public static Dictionary<string, string> GetHeadersFromRequest(HttpRequest request)
189+
public static Dictionary<string, string> GetHeadersFromRequest(HttpRequest request, SecureNativeOptions options)
144190
{
145191
var headers = new Dictionary<string, string>();
146-
try
192+
if (options?.GetPiiHeaders().Length > 0)
147193
{
148-
foreach (var key in request.Headers.Keys)
194+
try
195+
{
196+
foreach (var key in request.Headers.Keys)
197+
{
198+
if (!options.GetPiiHeaders().Contains(key))
199+
{
200+
headers.Add(key, request.Headers[key]);
201+
}
202+
}
203+
}
204+
catch (Exception)
205+
{
206+
// ignored
207+
}
208+
} else if (options != null && options.GetPiiRegexPattern() != "")
209+
{
210+
try
211+
{
212+
var pattern = new Regex(options.GetPiiRegexPattern());
213+
214+
foreach (var key in request.Headers.Keys)
215+
{
216+
if (!pattern.Match(key).Success)
217+
{
218+
headers.Add(key, request.Headers[key]);
219+
}
220+
}
221+
}
222+
catch (Exception)
149223
{
150-
headers.Add(key, request.Headers[key]);
224+
// ignored
151225
}
152226
}
153-
catch (Exception)
227+
else
154228
{
155-
// ignored
229+
try
230+
{
231+
foreach (var key in request.Headers.Keys)
232+
{
233+
if (!PiiHeaders.Contains(key))
234+
{
235+
headers.Add(key, request.Headers[key]);
236+
}
237+
}
238+
}
239+
catch (Exception)
240+
{
241+
// ignored
242+
}
156243
}
157244

158245
return headers;
@@ -203,7 +290,7 @@ public static string GetCookieValueFromRequest(HttpRequest request, string cooki
203290

204291
public static string GetClientIpFromRequest(HttpRequest request, SecureNativeOptions options)
205292
{
206-
if (options?.GetProxyHeaders() != null)
293+
if (options?.GetProxyHeaders().Length > 0)
207294
{
208295
foreach (var header in options.GetProxyHeaders())
209296
{

0 commit comments

Comments
 (0)