Skip to content

Commit

Permalink
APM: Support configuring skipped tag keys for the credit card obfusca…
Browse files Browse the repository at this point in the history
…tor (APMSP-1492) (#30680)
  • Loading branch information
ajgajg1134 authored Nov 6, 2024
1 parent 8e0f134 commit b833f62
Show file tree
Hide file tree
Showing 8 changed files with 52 additions and 3 deletions.
11 changes: 11 additions & 0 deletions cmd/trace-agent/test/testsuite/cards_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,17 @@ apm_config:
out: "?",
version: "v0.7",
},
{
conf: []byte(`
apm_config:
env: my-env
obfuscation:
credit_cards:
enabled: false
keep_values: ["credit_card_number"]`),
out: "4166 6766 6766 6746",
version: "v0.5",
},
} {
t.Run(string(tt.version)+"/"+tt.out, func(t *testing.T) {
if err := r.RunAgent(tt.conf); err != nil {
Expand Down
3 changes: 2 additions & 1 deletion pkg/config/setup/apm.go
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,7 @@ func setupAPM(config pkgconfigmodel.Setup) {
config.BindEnv("apm_config.install_time", "DD_INSTRUMENTATION_INSTALL_TIME")
config.BindEnv("apm_config.obfuscation.credit_cards.enabled", "DD_APM_OBFUSCATION_CREDIT_CARDS_ENABLED")
config.BindEnv("apm_config.obfuscation.credit_cards.luhn", "DD_APM_OBFUSCATION_CREDIT_CARDS_LUHN")
config.BindEnv("apm_config.obfuscation.credit_cards.keep_values", "DD_APM_OBFUSCATION_CREDIT_CARDS_KEEP_VALUES")
config.BindEnvAndSetDefault("apm_config.debug.port", 5012, "DD_APM_DEBUG_PORT")
config.BindEnv("apm_config.features", "DD_APM_FEATURES")
config.ParseEnvAsStringSlice("apm_config.features", func(s string) []string {
Expand Down Expand Up @@ -183,7 +184,7 @@ func setupAPM(config pkgconfigmodel.Setup) {
config.ParseEnvAsStringSlice("apm_config.filter_tags.reject", parseKVList("apm_config.filter_tags.reject"))
config.ParseEnvAsStringSlice("apm_config.filter_tags_regex.require", parseKVList("apm_config.filter_tags_regex.require"))
config.ParseEnvAsStringSlice("apm_config.filter_tags_regex.reject", parseKVList("apm_config.filter_tags_regex.reject"))

config.ParseEnvAsStringSlice("apm_config.obfuscation.credit_cards.keep_values", parseKVList("apm_config.obfuscation.credit_cards.keep_values"))
config.ParseEnvAsSliceMapString("apm_config.replace_tags", func(in string) []map[string]string {
var out []map[string]string
if err := json.Unmarshal([]byte(in), &out); err != nil {
Expand Down
1 change: 1 addition & 0 deletions pkg/flare/envvars.go
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ var allowedEnvvarNames = []string{
"DD_APM_SYMDB_DD_URL",
"DD_APM_OBFUSCATION_CREDIT_CARDS_ENABLED",
"DD_APM_OBFUSCATION_CREDIT_CARDS_LUHN",
"DD_APM_OBFUSCATION_CREDIT_CARDS_KEEP_VALUES",
"DD_APM_OBFUSCATION_ELASTICSEARCH_ENABLED",
"DD_APM_OBFUSCATION_ELASTICSEARCH_KEEP_VALUES",
"DD_APM_OBFUSCATION_ELASTICSEARCH_OBFUSCATE_SQL_VALUES",
Expand Down
13 changes: 11 additions & 2 deletions pkg/obfuscate/credit_cards.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,18 @@ import (

// creditCard maintains credit card obfuscation state and processing.
type creditCard struct {
luhn bool
luhn bool
keepValues map[string]struct{}
}

func newCCObfuscator(config *CreditCardsConfig) *creditCard {
keepValues := make(map[string]struct{}, len(config.KeepValues))
for _, sk := range config.KeepValues {
keepValues[sk] = struct{}{}
}
return &creditCard{
luhn: config.Luhn,
luhn: config.Luhn,
keepValues: keepValues,
}
}

Expand Down Expand Up @@ -57,6 +63,9 @@ func (o *Obfuscator) ObfuscateCreditCardNumber(key, val string) string {
if strings.HasPrefix(key, "_") {
return val
}
if _, ok := o.ccObfuscator.keepValues[key]; ok {
return val
}
if o.ccObfuscator.IsCardNumber(val) {
return "?"
}
Expand Down
8 changes: 8 additions & 0 deletions pkg/obfuscate/credit_cards_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -273,6 +273,14 @@ func TestIINIsSensitive(t *testing.T) {
})
}

func TestCCKeepValues(t *testing.T) {
possibleCard := "378282246310005"
o := NewObfuscator(Config{CreditCard: CreditCardsConfig{Enabled: true, KeepValues: []string{"skip_me"}}})

assert.Equal(t, possibleCard, o.ObfuscateCreditCardNumber("skip_me", possibleCard))
assert.Equal(t, "?", o.ObfuscateCreditCardNumber("obfuscate_me", possibleCard))
}

func BenchmarkIsSensitive(b *testing.B) {
run := func(str string, luhn bool) func(b *testing.B) {
cco := &creditCard{luhn: luhn}
Expand Down
4 changes: 4 additions & 0 deletions pkg/obfuscate/obfuscate.go
Original file line number Diff line number Diff line change
Expand Up @@ -264,6 +264,10 @@ type CreditCardsConfig struct {
// https://dev.to/shiraazm/goluhn-a-simple-library-for-generating-calculating-and-verifying-luhn-numbers-588j
// It reduces false positives, but increases the CPU time X3.
Luhn bool `mapstructure:"luhn"`

// KeepValues specifies tag keys that are known to not ever contain credit cards
// and therefore their values can be kept.
KeepValues []string `mapstructure:"keep_values"`
}

// NewObfuscator creates a new obfuscator
Expand Down
1 change: 1 addition & 0 deletions pkg/trace/agent/obfuscate.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ func (a *Agent) obfuscateSpan(span *pb.Span) {
for k, v := range span.Meta {
newV := o.ObfuscateCreditCardNumber(k, v)
if v != newV {
log.Debugf("obfuscating possible credit card under key %s from service %s", k, span.Service)
span.Meta[k] = newV
}
}
Expand Down
14 changes: 14 additions & 0 deletions releasenotes/notes/CCObfSkipKeys-b639ee1a05455030.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# Each section from every release note are combined when the
# CHANGELOG.rst is rendered. So the text needs to be worded so that
# it does not depend on any information only available in another
# section. This may mean repeating some details, but each section
# must be readable independently of the other.
#
# Each section note must be formatted as reStructuredText.
---

features:
- |
APM: New configuration apm_config.obfuscation.credit_cards.keep_values (DD_APM_OBFUSCATION_CREDIT_CARDS_KEEP_VALUES)
can be used to skip specific tag keys that are known to never contain credit card numbers. This is especially useful
in cases where a span tag value is a number that triggers false positives from the credit card obfuscator.

0 comments on commit b833f62

Please sign in to comment.