Skip to content

Hide client command arguments#11747

Closed
naglera wants to merge 4 commits into
redis:unstablefrom
naglera:unstable
Closed

Hide client command arguments#11747
naglera wants to merge 4 commits into
redis:unstablefrom
naglera:unstable

Conversation

@naglera

@naglera naglera commented Jan 23, 2023

Copy link
Copy Markdown
Contributor

In the event of an assertion failure, hide command arguments from the operator.

In some cases, private client information can be voluntarily exposed when a redis instance crashes due to an assertion failure.
This commit prevent וnintentional client info exposure.
Operators can still access the hidden data, but they must actively request it.
Any of the client info commands remains the unchanged.

@naglera naglera marked this pull request as ready for review January 23, 2023 12:34
@madolson

madolson commented Jan 24, 2023

Copy link
Copy Markdown
Contributor

This is from AWS, and I'll add some more context about the intention. We wanted to make sure that user data wasn't getting stored into log files, which has use cases around data sovereignty and security. The idea is that we should be able to produce a clean log file that can be stored and moved and only contain server information.

Some thoughts about this:

  1. I think crashes should have this information by default. Crashes are a pretty bad end state, and the end user is voluntarily choosing to send this information to us. We could add a disclaimer that their may be PII, but I don't want users omitting information that could help us debug it.
  2. I think it's generally assumed that logs may contain PII, other databases provide a parser ontop that will filter out data. We could provide some type of symbol that indicates that something might contain PII that could be parsed.
  3. There are other places in the logs where PII might get exposed, so I'm not sure why we are just targeting this place.

@yossigo

yossigo commented Jan 29, 2023

Copy link
Copy Markdown
Collaborator

There are other places in the logs where PII might get exposed, so I'm not sure why we are just targeting this place.

I agree. We should start by coming up with a list of those places and what could fall under this definition (e.g. client names, file names, redis.log() Lua output?).

@madolson

Copy link
Copy Markdown
Contributor

I agree. We should start by coming up with a list of those places and what could fall under this definition (e.g. client names, file names, redis.log() Lua output?).

Just adding on ACL users and any command arguments or partial query information (we dump that in a couple of places) since we can't know their content.

@oranagra Do you have any thoughts about providing some way to sanitize user data out of log files?

Comment thread src/networking.c Outdated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Why should we hide the client name?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

client name can hold sensitive information about the client purpose/ what the client does

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

regarding client-list, I hide clients names because it is printed inside crash reports.
The client names will not be hidden when calling client-list directly.

ok, now i understand that change better (had difficulties wrapping my head around the code).

i think the solution of using isBugReportStart and shouldHideClientInfo is ugly, and instead, it would be much nicer to just add a hide_user_info argument to catClientInfoString and getAllClientsInfoString.
the problem with that is that catClientInfoString is widely used, and we don't wanna modify all the calls.
the solution to that is to add an alias function, i.e. catClientInfoStringGeneric will take the argument and the existing catClientInfoString will just be a wrapper.

Comment thread src/config.c Outdated
@ranshid

ranshid commented Jan 30, 2023

Copy link
Copy Markdown
Contributor

I agree regarding the extended effort needed in this case. I think we should provide some sort of mask-pii mode for redis so it will avoid reporting internal data (key names, values, client names, addresses etc... as they might hold some info regarding customer application) but we will also need to provide the customer way to get that data in case he needs it (like turning off the pii masking per connection?)

@naglera

naglera commented Jan 30, 2023

Copy link
Copy Markdown
Contributor Author

but we will also need to provide the customer way to get that data in case he needs it

Customer will be able to watch those details by disabling hide-client-info (or in case it is disabled by default, they will not have to do anything)

Independent parser to run over logs and omit client parts is a complex alternative. It gets strings as input while in the config case we have the full logical context.

@ranshid

ranshid commented Jan 30, 2023

Copy link
Copy Markdown
Contributor

but we will also need to provide the customer way to get that data in case he needs it

Customer will be able to watch those details by disabling hide-client-info (or in case it is disabled by default, they will not have to do anything)

Independent parser to run over logs and omit client parts is a complex alternative. It gets strings as input while in the config case we have the full logical context.

you mean that admin would be able to do multi; config set hide-client-info no; client list; config set hide-client-info yes; exec?
so yes.. it would be possible but I suspect it might have some strange issues, like keyspace notification data and other potential data which can propagate to other clients. I agree that we can offer this at first stage, but I think this will require some thoughts

@oranagra

Copy link
Copy Markdown
Member

Not a fan of the idea, but It could be an acl user flag.
This way an existing monitoring application will not require modifications (like the above multi)

But I still don't understand why we want to filter client list. Unlike the crash log, it's just a command, like KEYS or GET, and can be blocked by acl

@ranshid

ranshid commented Jan 31, 2023

Copy link
Copy Markdown
Contributor

Not a fan of the idea, but It could be an acl user flag. This way an existing monitoring application will not require modifications (like the above multi)

But I still don't understand why we want to filter client list. Unlike the crash log, it's just a command, like KEYS or GET, and can be blocked by acl

It is true that it can be blocked, but in cases were Redis is provided as a service sometimes clients would like to prevent operators from accessing private data while the operators would still need some tools in order to debug/manage the service .commands like slowlog, info client list etc... can be used by both operator and clients while having this flag can help reduce the potential pii leakage

Comment thread src/debug.c Outdated
Comment thread src/debug.c Outdated
Comment thread src/networking.c Outdated
Comment thread src/networking.c Outdated
@yossigo

yossigo commented Jan 31, 2023

Copy link
Copy Markdown
Collaborator

@ranshid I think we need to consider the use case you describe as a separate feature. Preventing PII from getting into log files is one thing. Removing PII from the output of administrative commands is another thing - it takes us to multi-level admin privileges, which is a deeper rabbit hole.

@ranshid

ranshid commented Jan 31, 2023

Copy link
Copy Markdown
Contributor

@ranshid I think we need to consider the use case you describe as a separate feature. Preventing PII from getting into log files is one thing. Removing PII from the output of administrative commands is another thing - it takes us to multi-level admin privileges, which is a deeper rabbit hole.

I agree that some deeper thought should be placed to this, I was only pointing out some use cases which we encountered in AWS. As said it is possible to use some external tool to remove PII from logs and command outputs, but in such cases customers cannot realy validate the efficiency of such tool so having a redis built-in mechanism can help build trust with external users.

@naglera

naglera commented Jan 31, 2023

Copy link
Copy Markdown
Contributor Author

@oranagra & @ranshid - regarding client-list, I hide clients names because it is printed inside crash reports.
The client names will not be hidden when calling client-list directly.
Thus the multi you suggested isn't necessary

Comment thread src/config.c Outdated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

i think the name of this config is not clear enough.
if it keeps it's current purpose, it should say "log".
alternatively we need to design where this is going before making any changes.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

p.s. documentation in redis.conf is missing.

Comment thread src/debug.c Outdated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

maybe rename "Show" to "Log"

Comment thread src/networking.c Outdated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

hide_user_info is misleading, it could mean that we hide the ACL user name.

actually, i'll argue that again that i don't see why CLIENT SETNAME is PII, and if it is, then the ACL user name could be too.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Ack, client name will not be redacted

Comment thread src/networking.c Outdated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

maybe it should say --redacted-- instead of remain empty?

Comment thread src/debug.c Outdated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

if we hide the arguments, let's at least print the argc instead, and maybe a bold "redacted" message.

@oranagra

oranagra commented Feb 8, 2023

Copy link
Copy Markdown
Member

we discussed this in a core-team meeting and concluded that we would like to proceed only after we prepare some detailed list of everything we could want to redact (maybe host names and other things).

@naglera

naglera commented Feb 8, 2023

Copy link
Copy Markdown
Contributor Author

Ack, I will create a draft list for discussion

@naglera

naglera commented Feb 12, 2023

Copy link
Copy Markdown
Contributor Author

Those are the points I found which we might spill to logs some PII.
If we choose to include scripts and files names, the list my expand.
Also if there are places where we spill lua outputs let me know (I am not aware of such)

File Method Comments
debug.c _serverAssertPrintClientInfo command argumants
  logCurrentClient command arguments
replication.c showLatestBacklog  
  replicationFeedStreamFromMasterStream in if(0)
slowlog.c slowlogCommand Not sure if its counted as log or command

Please let me know if I missed something

@oranagra

Copy link
Copy Markdown
Member

I don't think SLOWLOG is part of it, if it did then MONITOR and CLIENT LIST are too.
what about logStackContent?

@naglera

naglera commented Feb 13, 2023

Copy link
Copy Markdown
Contributor Author

I agree regarding slowLogCommand lets leave it out of scope.
Isn't logStackContent logs the stack trace? If so in what cases does stack trace contains PII?

@oranagra

Copy link
Copy Markdown
Member

it doesn't log the stack "trace". it logs the stack contents (could contain variables)

@madolson

Copy link
Copy Markdown
Contributor

If we choose to include scripts and files names, the list my expand.

I would be inclined to say function names count and file names do not. Typically file names are administrator, and we can ask them to set it to something not related to user data.

@naglera

naglera commented Feb 15, 2023

Copy link
Copy Markdown
Contributor Author

Updated list

File Method Comments
debug.c _serverAssertPrintClientInfo Command arguments
  logCurrentClient Command arguments
logStackContent Stack frames content
replication.c showLatestBacklog Log latest commands
  replicationFeedStreamFromMasterStream In if(0)

@naglera

naglera commented Feb 27, 2023

Copy link
Copy Markdown
Contributor Author

Hide replication backlog & stack frame and fix comments

@naglera naglera reopened this Feb 27, 2023
@naglera naglera closed this Jul 2, 2023
@naglera naglera force-pushed the unstable branch 2 times, most recently from e848b0c to 2617412 Compare July 2, 2023 08:22
@madolson

madolson commented Jul 2, 2023

Copy link
Copy Markdown
Contributor

@naglera Are you abandoning this effort?

@naglera

naglera commented Jul 3, 2023

Copy link
Copy Markdown
Contributor Author

No, horrible git accident, I started this commit from unstable, and it closed automatically when I pulled from upstream.

By the way, @madolson, are you also approving the list? #11747 (comment)

@madolson

madolson commented Jul 3, 2023

Copy link
Copy Markdown
Contributor

@naglera Yeah, that looked good to me :)

@sundb

sundb commented Mar 11, 2024

Copy link
Copy Markdown
Collaborator

@naglera What about this test code? since replicationFeedStreamFromMasterStream needs to be hidden, i think it should too.

redis/src/t_stream.c

Lines 352 to 360 in 5fdaa53

void streamLogListpackContent(unsigned char *lp) {
unsigned char *p = lpFirst(lp);
while(p) {
unsigned char buf[LP_INTBUF_SIZE];
int64_t v;
unsigned char *ele = lpGet(p,&v,buf);
serverLog(LL_WARNING,"- [%d] '%.*s'", (int)v, (int)v, ele);
p = lpNext(lp,p);
}

Comment thread src/server.h Outdated
Comment thread src/debug.c Outdated
Comment thread src/replication.c Outdated
naglera and others added 3 commits March 11, 2024 10:45
fix spaces

Co-authored-by: debing.sun <debing.sun@redis.com>
fix spaces

Co-authored-by: debing.sun <debing.sun@redis.com>
fix log

Co-authored-by: debing.sun <debing.sun@redis.com>
@naglera

naglera commented Mar 11, 2024

Copy link
Copy Markdown
Contributor Author

Hi @sundb, I'm not sure if we actually use streamLogListpackContent, but if it's being used locally to debug, I don't want to complicate things. I'm also not sure if this PR is still relevant.

Comment thread src/debug.c
Comment on lines +1085 to +1086
if (j >= clientArgsToLog(c)){
serverLog(LL_WARNING|LL_RAW,"client->argv[%d]: *redacted*\n", j);

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Suggested change
if (j >= clientArgsToLog(c)){
serverLog(LL_WARNING|LL_RAW,"client->argv[%d]: *redacted*\n", j);
if (j >= clientArgsToLog(c)) {
serverLog(LL_WARNING|LL_RAW,"client->argv[%d]: *redacted*", j);

Comment thread src/debug.c
serverLog(LL_WARNING|LL_RAW,"argc: '%d'\n", cc->argc);
for (j = 0; j < cc->argc; j++) {
if (j >= clientArgsToLog(cc)){
serverLog(LL_WARNING|LL_RAW,"argv[%d]: *redacted*\n", j);

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Suggested change
serverLog(LL_WARNING|LL_RAW,"argv[%d]: *redacted*\n", j);
serverLog(LL_WARNING|LL_RAW,"argv[%d]: *redacted*", j);

@CLAassistant

Copy link
Copy Markdown

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.
You have signed the CLA already but the status is still pending? Let us recheck it.

@sundb sundb mentioned this pull request Jul 8, 2024
sundb added a commit that referenced this pull request Jul 9, 2024
This PR is based on the commits from PR #11747.

In the event of an assertion failure, hide command arguments from the
operator.

In some cases, private client information can be voluntarily exposed
when a redis instance crashes due to an assertion failure.
This commit prevent וnintentional client info exposure.
Operators can still access the hidden data, but they must actively
request it.
Any of the client info commands remains the unchanged.

### Config
Add a new config `hide-user-data-from-log` to turn this feature on and
off, default off.

---------

Co-authored-by: naglera <anagler123@gmail.com>
Co-authored-by: naglera <58042354+naglera@users.noreply.github.com>
@sundb

sundb commented Jul 19, 2024

Copy link
Copy Markdown
Collaborator

Close via #13400

@sundb sundb closed this Jul 19, 2024
sundb pushed a commit that referenced this pull request Jan 4, 2026
This PR continues the work from
[#13400](#13400), following the
discussion in
[#11747](#11747 (comment)),
to further ensure sensitive user data is not exposed in logs when
hide_user_data_from_log is enabled.

- Introduce redactLogCstr() helper for safe, centralized log redaction.
- Update ACL and networking log messages to use redacted values where
appropriate.
- Prevent leaking raw query buffer contents.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

7 participants