Archive
Obfuscating sensitive data in Azure Application Insights
While working with a legacy Api which where called via GET request exposing sensitive data in query strings, I saw this sensitive data in Application Insight and wanted to obfuscate them.
This can be done by creating a Customer ITelemetryInitializer, since the API Dependency to the main Application only when this dependency log is made do we want to obfuscate the data, other scenarios can be covered in other ways. With a DependencyTelemetry it is possible to test if I HTTP request. If the request do have any query parameter filtering should now be done from the source list of query strings which is passed in via the constructor. See the code below for the finished QueryStringFilterTelemetryInitializer
using Microsoft.ApplicationInsights.Channel;
using Microsoft.ApplicationInsights.DataContracts;
using Microsoft.ApplicationInsights.Extensibility;
using System;
using System.Collections.Generic;
namespace Application
{
public class QueryStringFilterTelemetryInitializer : ITelemetryInitializer
{
public QueryStringFilterTelemetryInitializer(IEnumerable<string> queryStringSource)
{
QueryStringSource=queryStringSource;
}
public IEnumerable<string> QueryStringSource { get; }
public void Initialize(ITelemetry telemetry)
{
var dependencyTelemetry = telemetry as DependencyTelemetry;
if (dependencyTelemetry == null)
return;
if (dependencyTelemetry.Type.Equals("http", StringComparison.InvariantCultureIgnoreCase))
{
var uri = new Uri(dependencyTelemetry.Data);
var queryDictionary = System.Web.HttpUtility.ParseQueryString(uri.Query);
if (queryDictionary != null || !queryDictionary.HasKeys())
return;
foreach (var source in QueryStringSource)
{
var queryValue = queryDictionary[source];
if (queryDictionary !=null && !string.IsNullOrEmpty(queryValue))
{
dependencyTelemetry.Data = dependencyTelemetry.Data.Replace(queryValue, "***********");
}
}
}
}
}
}
With the QueryFilterTelemetryInitializer created we can now instantiate it in our startup.cs file
public virtual void ConfigureServices(IServiceCollection services)
{
services.AddSingleton<ITelemetryInitializer>(
new QueryStringFilterTelemetryInitializer(
new List<string>() { "SOMEQUERYSTRING" }));
services.AddApplicationInsightsTelemetry();
..
..
..
}
Instead of providing the list of string at compile time you can also load them in via a config file as shown below
{
"QueryStrings": [
"querystring0",
"querystring1",
"querystring2"
],
}
and in the startup class replace with this line
services.AddSingleton<ITelemetryInitializer>(new QueryStringFilterTelemetryInitializer(Configuration.GetSection("QueryStrings")?.Get<List<string>>().ToArray()));
This is how it will look in the Data in Azure AppInsights
https://URL/API/?queryString0=**********