[APMS-18584] Fix authentication obfuscation on HELLO and MIGRATE verbs#5350
[APMS-18584] Fix authentication obfuscation on HELLO and MIGRATE verbs#5350
Conversation
Typing analysisIgnored filesThis PR clears 1 ignored file. It increases the percentage of typed files from 42.43% to 42.54% (+0.11%). Ignored files (+0-1)✅ Cleared:Note: Ignored files are excluded from the next sections. Untyped methodsThis PR introduces 2 untyped methods and 2 partially typed methods. It decreases the percentage of typed methods from 60.11% to 60.0% (-0.11%). Untyped methods (+2-0)❌ Introduced:Partially typed methods (+2-0)❌ Introduced:Untyped other declarationsThis PR introduces 1 untyped other declaration. It increases the percentage of typed other declarations from 77.03% to 77.11% (+0.08%). Untyped other declarations (+1-0)❌ Introduced:If you believe a method or an attribute is rightfully untyped or partially typed, you can add |
|
✅ Tests 🎉 All green!❄️ No new flaky tests detected 🎯 Code Coverage 🔗 Commit SHA: e8458a1 | Docs | Datadog PR Page | Was this helpful? Give us feedback! |
BenchmarksBenchmark execution time: 2026-02-11 18:24:20 Comparing candidate commit e8458a1 in PR branch Found 3 performance improvements and 0 performance regressions! Performance is the same for 41 metrics, 2 unstable metrics. scenario:tracing - 100 span trace - no writer
scenario:tracing - Propagation - Datadog
scenario:tracing - Tracing.log_correlation
|
| AUTH_COMMANDS.include?(verb) | ||
| case verb | ||
| when *AUTH_COMMANDS | ||
| return %w[AUTH ?] |
There was a problem hiding this comment.
is this intended to change "AUTH ?" string to ["AUTH", "?"] array?
There was a problem hiding this comment.
It does return an array ["AUTH", "?"] but then format_command_args will turn it into a string
| def format_command_args(command_args) | ||
| command_args = resolve_command_args(command_args) | ||
| return 'AUTH ?' if auth_command?(command_args) | ||
| command_args = obfuscate_auth_args(command_args) |
There was a problem hiding this comment.
we were returning a string before for an auth command, now for the auth command and for hello and migrate commands we are duping and mutating all command args - could we avoid duping the whole array?
There was a problem hiding this comment.
I think there is no way around creating a nearly complete copy of the array one way or another but maybe constructing the new array one element at a time is faster than duping and then removing an element? Don't know how important this optimization is though.
There was a problem hiding this comment.
I tried to edit the array in-place but it was causing issues as arrays coming from redis are frozen. I will run some benchmarks to see what's the faster solution
| module Contrib | ||
| module Redis | ||
| module Quantize | ||
| type command = ::Array[::String | ::Symbol | command] |
There was a problem hiding this comment.
This says that command can be an infinitely nested array? Is that right?
| verb = command_args.first.to_s | ||
| AUTH_COMMANDS.include?(verb) | ||
| case verb | ||
| when *AUTH_COMMANDS |
There was a problem hiding this comment.
This handles commands in all upper case and all lower case, but according to https://redis.io/docs/latest/commands/command/ the commands are case insensitive. Given that this code deals with redaction I think it should e.g. lowercase the commands prior to matching rather than only handling all upper or all lower case (which, I assume, is the current behavior of supported ruby redis clients?).
There was a problem hiding this comment.
I do agree with Oleg, but from pure performance perspective, commands need to go through normalization process first, that would allow us to drop upper/lower case difference.
In addition this will allow us to stop deconstructing arrays of 2 elements every time (at this point we can just list values with comma).
| end | ||
|
|
||
| context 'with keys' do | ||
| let(:args) { %w[MIGRATE 127.0.0.1 6379 "" 0 5000 AUTH dog KEYS foo] } |
There was a problem hiding this comment.
I think there should also be tests where "auth" is used as the value, e.g.:
MIGRATE 127.0.0.1 6379 "" 0 5000 AUTH AUTH KEYS AUTH
MIGRATE 127.0.0.1 6379 "AUTH" 0 5000 AUTH dog KEYS foo
Can the IP address be a hostname? If so that should also ideally be tested with "AUTH" as value.
|
@codex Analyze obfuscation method for performance and memory footprint. Look for bugs and potential issues. |
Summary
Committed: PR created: Follow-up PR title: “Follow-up: harden Redis AUTH obfuscation matching and edge cases”. Testing
|
|
So many links in the codex comment, but none to the PR it made? |
|
I think also this PR should use "redaction"? "Obfuscation" means something quite a bit different to me (for example, it should transform different values to different values, replacing all input with a fixed value - the question mark in this case - is not what obfuscation does) |
|
I am not seeing the PR codex made at all. |
|
@p-datadog There is a button you have to press inside the Codex View Task |
|
Closing as the fix has been implemented on the agent (https://github.com/DataDog/datadog-agent/releases/tag/7.75.4) |
What does this PR do?
This PR fixes the leaking of sensitive data in HELLO and MIGRATE verbs on redis instrumentation
Motivation:
Customer had sensitive data that was leaked by HELLO. It was introduced in Redis 6, however MIGRATE can also uses AUTH since 4.0.7.
Change log entry
Yes. Add sensitive-data obfuscation for Redis
HELLOandMIGRATEverbsAdditional Notes:
I tried to implement something future-proof, unfortunately, to keep compatibility with Redis < 6, we must support the
requirepassmechanism. Which means that sometimes AUTH will only have 1 arg, and sometimes 2. And in the case of MIGRATE, it can be followed by KEYS, which we do not want to remove. So the solution implemented is not future-proof, and we should keep track of new redis versions to ensure we do not miss new verbs that uses AUTH.How to test the change?
CI