Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

contrib/go-redis/redis.v8: add Option to Exclude Raw Command #1026

Closed
wants to merge 12 commits into from

Conversation

sjmtan
Copy link
Contributor

@sjmtan sjmtan commented Oct 8, 2021

Intends on solving #1022.

I couldn't figure out how to get the tests run locally sadly, so 🤞🏼 that this works.

@rama-kundurthi
Copy link

@shannontan-bolt : Thanks for working on this. I am also in need of this change.

Copy link
Member

@felixge felixge left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for this PR @shannontan-bolt and sorry for not receiving a reply earlier.

I'm on the profiling team, so please take my comments with a grain of salt, but here is what I think:

  • This change is absolutely needed. This is a DDoS vector and a potential leak for PII. I would suggest excludeRawCommand to be true by default.
  • The code LGTM (but I have not tested it beyond visual inspection).

@knusbaum PTAL as well.

@@ -102,14 +102,18 @@ func (ddh *datadogHook) BeforeProcess(ctx context.Context, cmd redis.Cmder) (con
raw := cmd.String()
length := strings.Count(raw, " ")
p := ddh.params
opts := make([]ddtrace.StartSpanOption, 0, 5+len(ddh.additionalTags)+1) // 5 options below + for additionalTags + for analyticsRate
var opts []ddtrace.StartSpanOption
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

NIT: Generally I'm okay with not pre-allocating the arrays backing a slice unless it has a significant performance impact. I'm not sure if this analysis has been done here, but assuming it was, this change here could be a small performance regression.

Have you considered just keeping this line (and the one in BeforeProcessPipeline) as-is? As far as I can tell that should work just fine.

Copy link
Contributor

@gbbr gbbr left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This LGTM. Just a few nits regarding spaces, if you could please cut down 🙏🏻

Comment on lines +112 to +116

if !p.config.excludeRawCommand {
opts = append(opts, tracer.Tag("redis.raw_command", raw))
}

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if !p.config.excludeRawCommand {
opts = append(opts, tracer.Tag("redis.raw_command", raw))
}
if !p.config.excludeRawCommand {
opts = append(opts, tracer.Tag("redis.raw_command", raw))
}

Comment on lines +149 to +155

if !p.config.excludeRawCommand {
opts = append(opts,
tracer.Tag("redis.raw_command", raw),
tracer.Tag(ext.ResourceName, raw))
}

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if !p.config.excludeRawCommand {
opts = append(opts,
tracer.Tag("redis.raw_command", raw),
tracer.Tag(ext.ResourceName, raw))
}
if !p.config.excludeRawCommand {
opts = append(opts,
tracer.Tag("redis.raw_command", raw),
tracer.Tag(ext.ResourceName, raw))
}

@gbbr gbbr changed the title Add Option to Exclude Raw Command contrib/go-redis/redis.v8: add Option to Exclude Raw Command Nov 5, 2021
Comment on lines +63 to +64
// WithExcludeRawCommand sets the option to exclude the raw command
// for when the command/cache might contain sensitive data
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't understand this part. The Datadog Agent obfuscates this tag and hides all parameters. Why would the fact that it contains sensitive data be an issue?

Suggested change
// WithExcludeRawCommand sets the option to exclude the raw command
// for when the command/cache might contain sensitive data
// SkipRawCommand determines the integration to skip setting the raw command
// in the redis.raw_command tag of a span.

As for the doc, we should be a bit more specific on what it does.


// WithExcludeRawCommand sets the option to exclude the raw command
// for when the command/cache might contain sensitive data
func WithExcludeRawCommand(exclude bool) ClientOption {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
func WithExcludeRawCommand(exclude bool) ClientOption {
func SkipRawCommand(skip bool) ClientOption {

I think this would be better, unless it's bad that we don't have the With* prefix?

@gbbr gbbr added this to the 1.35.0 milestone Nov 5, 2021
if !p.config.excludeRawCommand {
opts = append(opts,
tracer.Tag("redis.raw_command", raw),
tracer.Tag(ext.ResourceName, raw))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry for missing this. The resource name is 100% mandatory for all spans. We can not leave it out.

@sjmtan
Copy link
Contributor Author

sjmtan commented Nov 6, 2021

@gbbr, to be perfectly honest, it might be easier if you try to fix this. I find that my local environment regarding dependencies + tests for this repo is kinda messed up so I find it hard to test this work on it without my IDE complaining about missing dependencies after syncing the go.mod file.

That's very confusing though that the ResourceName requires the raw command. The raw command contains the entire value that we are sending to Redis, which can include sensitive values. Imagine for example that you wanted to put IP address as a rate limit key. The real issue for us was that we were trying to save an object of data in a Redis cache and that meant this large blob was putting put as a tag with tracing.

If it is required though, which is fine, we should probably use something else?

@gbbr
Copy link
Contributor

gbbr commented Nov 8, 2021

@gbbr, to be perfectly honest, it might be easier if you try to fix this. I find that my local environment regarding dependencies + tests for this repo is kinda messed up so I find it hard to test this work on it without my IDE complaining about missing dependencies after syncing the go.mod file.

Not exactly sure I understand what there is to fix? All you need to do is to run redis:3.2 locally in order for the test to run, and forward the appropriate port. When running tests for integrations, simply check our CircleCI config for the image needed and for the port that needs to be exposed. Maybe we should put this into the docs somewhere. So, you run docker run -p 6379:6379 redis:3.2 and then INTEGRATION=1 go test -v ./contrib/go-redis/redis.v8/.... Does this not work for you?

That's very confusing though that the ResourceName requires the raw command. The raw command contains the entire value that we are sending to Redis, which can include sensitive values. Imagine for example that you wanted to put IP address as a rate limit key. [...]

Let's continue this discussion in the issue you've opened (#1022). I've already explained there that these values are obfuscated, and no sensitive values will leave the Datadog Agent.

The real issue for us was that we were trying to save an object of data in a Redis cache and that meant this large blob was putting put as a tag with tracing.

Answered in the issue.

@gbbr
Copy link
Contributor

gbbr commented Dec 14, 2021

Superseded by #1091

@gbbr gbbr closed this Dec 14, 2021
@knusbaum knusbaum removed this from the 1.35.0 milestone Dec 16, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants