Skip to content

Commit

Permalink
Merge pull request #4 from securenative/dev
Browse files Browse the repository at this point in the history
Support pii data remove from config
  • Loading branch information
inbaltako authored Nov 29, 2020
2 parents 96df344 + 941771f commit 24e837b
Show file tree
Hide file tree
Showing 7 changed files with 350 additions and 29 deletions.
69 changes: 69 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -195,3 +195,72 @@ public void WebhookEndpoint()
var isVerified = securenative.VerifyRequestPayload(Request);
}
```

## Extract proxy headers from cloud providers

You can specify custom header keys to allow extraction of client ip from different providers.
This example demonstrates the usage of proxy headers for ip extraction from Cloudflare.

### Option 1: Using config file
```json
{
"SECURENATIVE_API_KEY": "YOUR_API_KEY",
"SECURENATIVE_PROXY_HEADERS": ["CF-Connecting-IP"]
}
```

Initialize sdk as shown above.

### Options 2: Using ConfigurationBuilder

```dotenv
using SecureNative.SDK;
SecureNativeOptions Options = ConfigurationManager.ConfigBuilder()
.WithApiKey("API_KEY"))
.WithProxyHeaders(new ["CF-Connecting-IP"])
.Build());
var securenative = Client.Init(Options);
```

```go
options := config.DefaultSecureNativeOptions()
options.ApiKey = "YOUR_API_KEY"
options.ProxyHeaders = []string{"CF-Connecting-IP"}

sn, err := sdk.InitSDK(options)
if err != nil {
log.Fatal("Do some error handling")
}
```

## Remove PII Data From Headers

By default, SecureNative SDK remove any known pii headers from the received request.
We also support using custom pii headers and regex matching via configuration, for example:

### Option 1: Using config file
```json
{
"SECURENATIVE_API_KEY": "YOUR_API_KEY",
"SECURENATIVE_PII_HEADERS": ["apiKey"]
}
```

Initialize sdk as shown above.

### Options 2: Using ConfigurationBuilder

```dotenv
using SecureNative.SDK;
SecureNativeOptions Options = ConfigurationManager.ConfigBuilder()
.WithApiKey("API_KEY"))
.WithPiiRegexPattern(@"((?i)(http_auth_)(\w+)?)")
.Build());
var securenative = Client.Init(Options);
```
38 changes: 27 additions & 11 deletions SecureNative.SDK/Config/SecureNativeConfigurationBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,20 +14,24 @@ public class SecureNativeConfigurationBuilder
private string LogLevel { get; set; }
private string FailOverStrategy { get; set; }
private string[] ProxyHeaders { get; set; }
private string[] PiiHeaders { get; set; }
private string PiiRegexPattern { get; set; }

public static SecureNativeConfigurationBuilder DefaultConfigBuilder()
{
return new SecureNativeConfigurationBuilder()
.WithApiKey("")
.WithApiUrl("https://api.securenative.com/collector/api/v1")
.WithInterval(1000)
.WithTimeout(1500)
.WithMaxEvents(1000)
.WithAutoSend(true)
.WithDisable(false)
.WithLogLevel("fatal")
.WithFailOverStrategy(Enums.FailOverStrategy.FAIL_OPEN)
.WithProxyHeaders(new string[]{});
.WithApiKey("")
.WithApiUrl("https://api.securenative.com/collector/api/v1")
.WithInterval(1000)
.WithTimeout(1500)
.WithMaxEvents(1000)
.WithAutoSend(true)
.WithDisable(false)
.WithLogLevel("fatal")
.WithFailOverStrategy(Enums.FailOverStrategy.FAIL_OPEN)
.WithProxyHeaders(new string[] { })
.WithPiiHeaders(new string[] { })
.WithPiiRegexPattern("");
}

public SecureNativeConfigurationBuilder WithApiKey(string apiKey)
Expand Down Expand Up @@ -90,9 +94,21 @@ public SecureNativeConfigurationBuilder WithProxyHeaders(string[] proxyHeaders)
return this;
}

public SecureNativeConfigurationBuilder WithPiiHeaders(string[] piiHeaders)
{
PiiHeaders = piiHeaders;
return this;
}

public SecureNativeConfigurationBuilder WithPiiRegexPattern(string piiRegexPattern)
{
PiiRegexPattern = piiRegexPattern;
return this;
}

public SecureNativeOptions Build()
{
return new SecureNativeOptions(ApiKey, ApiUrl, Interval, MaxEvents, Timeout, AutoSend, Disable, LogLevel, FailOverStrategy, ProxyHeaders);
return new SecureNativeOptions(ApiKey, ApiUrl, Interval, MaxEvents, Timeout, AutoSend, Disable, LogLevel, FailOverStrategy, ProxyHeaders, PiiHeaders, PiiRegexPattern);
}
}
}
26 changes: 25 additions & 1 deletion SecureNative.SDK/Config/SecureNativeOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,10 @@ public class SecureNativeOptions
private string LogLevel { get; set; }
private string FailOverStrategy { get; set; }
private string[] ProxyHeaders { get; set; }
private string[] PiiHeaders { get; set; }
private string PiiRegexPattern { get; set; }

public SecureNativeOptions(string apiKey, string apiUrl, int interval, int maxEvents, int timeout, bool autoSend, bool disable, string logLevel, string failOverStrategy, string[] proxyHeaders)
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)
{
ApiKey = apiKey;
ApiUrl = apiUrl;
Expand All @@ -25,6 +27,8 @@ public SecureNativeOptions(string apiKey, string apiUrl, int interval, int maxEv
LogLevel = logLevel;
FailOverStrategy = failOverStrategy;
ProxyHeaders = proxyHeaders;
PiiHeaders = piiHeaders;
PiiRegexPattern = piiRegexPattern;
}

public string GetApiKey()
Expand Down Expand Up @@ -126,5 +130,25 @@ public void SetProxyHeaders(string[] value)
{
ProxyHeaders = value;
}

public string[] GetPiiHeaders()
{
return PiiHeaders;
}

public void SetPiiHeaders(string[] value)
{
PiiHeaders = value;
}

public string GetPiiRegexPattern()
{
return PiiRegexPattern;
}

public void SetPiiRegexPattern(string value)
{
PiiRegexPattern = value;
}
}
}
4 changes: 2 additions & 2 deletions SecureNative.SDK/Context/SecureNativeContextBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ public SecureNativeContextBuilder WithClientToken(string clientToken)

public static SecureNativeContextBuilder FromHttpRequest(HttpRequest request, SecureNativeOptions options)
{
var headers = RequestUtils.GetHeadersFromRequest(request);
var headers = RequestUtils.GetHeadersFromRequest(request, options);

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

public static SecureNativeContextBuilder FromHttpRequest(HttpWebRequest request, SecureNativeOptions options)
{
var headers = RequestUtils.GetHeadersFromRequest(request);
var headers = RequestUtils.GetHeadersFromRequest(request, options);

var clientToken = RequestUtils.GetCookieValueFromRequest(request, RequestUtils.SecurenativeCookie);
if (string.IsNullOrEmpty(clientToken))
Expand Down
115 changes: 101 additions & 14 deletions SecureNative.SDK/Utils/RequestUtils.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Text.RegularExpressions;
using Microsoft.AspNetCore.Http;
using SecureNative.SDK.Config;

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

public static Dictionary<string, string> GetHeadersFromRequest(HttpWebRequest request)
public static Dictionary<string, string> GetHeadersFromRequest(HttpWebRequest request, SecureNativeOptions options)
{
var headers = new Dictionary<string, string>();
try
if (options?.GetPiiHeaders().Length > 0)
{
foreach (var key in request.Headers.AllKeys)
try
{
foreach (var key in request.Headers.AllKeys)
{
if (!options.GetPiiHeaders().Contains(key))
{
headers.Add(key, request.Headers[key]);
}
}
}
catch (Exception)
{
// ignored
}
} else if (options != null && options.GetPiiRegexPattern() != "")
{
try
{
var pattern = new Regex(options.GetPiiRegexPattern());

foreach (var key in request.Headers.AllKeys)
{
if (!pattern.Match(key).Success)
{
headers.Add(key, request.Headers[key]);
}
}
}
catch (Exception)
{
headers.Add(key, request.Headers[key]);
// ignored
}
}
catch (Exception)
else
{
// ignored
try
{
foreach (var key in request.Headers.AllKeys)
{
if (!PiiHeaders.Contains(key))
{
headers.Add(key, request.Headers[key]);
}
}
}
catch (Exception)
{
// ignored
}
}

return headers;
Expand Down Expand Up @@ -80,7 +126,7 @@ private static string ParseCookie(string cookieString, string cookieName)

public static string GetClientIpFromRequest(HttpWebRequest request, SecureNativeOptions options)
{
if (options?.GetProxyHeaders() != null)
if (options?.GetProxyHeaders().Length > 0)
{
foreach (var header in options.GetProxyHeaders())
{
Expand Down Expand Up @@ -140,19 +186,60 @@ public static string GetRemoteIpFromRequest(HttpWebRequest request)
return string.Empty;
}

public static Dictionary<string, string> GetHeadersFromRequest(HttpRequest request)
public static Dictionary<string, string> GetHeadersFromRequest(HttpRequest request, SecureNativeOptions options)
{
var headers = new Dictionary<string, string>();
try
if (options?.GetPiiHeaders().Length > 0)
{
foreach (var key in request.Headers.Keys)
try
{
foreach (var key in request.Headers.Keys)
{
if (!options.GetPiiHeaders().Contains(key))
{
headers.Add(key, request.Headers[key]);
}
}
}
catch (Exception)
{
// ignored
}
} else if (options != null && options.GetPiiRegexPattern() != "")
{
try
{
var pattern = new Regex(options.GetPiiRegexPattern());

foreach (var key in request.Headers.Keys)
{
if (!pattern.Match(key).Success)
{
headers.Add(key, request.Headers[key]);
}
}
}
catch (Exception)
{
headers.Add(key, request.Headers[key]);
// ignored
}
}
catch (Exception)
else
{
// ignored
try
{
foreach (var key in request.Headers.Keys)
{
if (!PiiHeaders.Contains(key))
{
headers.Add(key, request.Headers[key]);
}
}
}
catch (Exception)
{
// ignored
}
}

return headers;
Expand Down Expand Up @@ -203,7 +290,7 @@ public static string GetCookieValueFromRequest(HttpRequest request, string cooki

public static string GetClientIpFromRequest(HttpRequest request, SecureNativeOptions options)
{
if (options?.GetProxyHeaders() != null)
if (options?.GetProxyHeaders().Length > 0)
{
foreach (var header in options.GetProxyHeaders())
{
Expand Down
Loading

0 comments on commit 24e837b

Please sign in to comment.