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

Using SecretString to store senstive values in copy stmt #2144

Closed
MichaelScofield opened this issue Aug 10, 2023 · 5 comments · Fixed by #3804
Closed

Using SecretString to store senstive values in copy stmt #2144

MichaelScofield opened this issue Aug 10, 2023 · 5 comments · Fixed by #3804
Labels
C-feature Category Features good first issue Good for newcomers help wanted Extra attention is needed

Comments

@MichaelScofield
Copy link
Collaborator

MichaelScofield commented Aug 10, 2023

What problem does the new feature solve?

copy stmt can carry senstive data like S3 API key or secret. This makes leaking easily.

What does the feature do?

Right now the senstive values are all stored in plain strings, and we have to write special redacting codes for printing them. It's better we use SecretString for them.

A follow up of #3744.

Implementation challenges

@MichaelScofield MichaelScofield added help wanted Extra attention is needed C-feature Category Features labels Aug 10, 2023
@tisonkun
Copy link
Collaborator

tisonkun commented Apr 7, 2024

Current code -

A thoroughly solution should be, supporting reconstruct query from statements, and redact options of copy stmt on demand.

See:

match self.query_statement(stmt, query_ctx.clone()).await {
    Ok(output) => {
        let output_result =
            query_interceptor.post_execute(output, query_ctx.clone());
        results.push(output_result);
    }
    Err(e) => {
        let redacted = sql::util::redact_sql_secrets(query.as_ref());
        error!(e; "Failed to execute query: {redacted}");

        results.push(Err(e));
        break;
    }
}

We currently print all the query if any of the statement failed to execute.

@MichaelScofield MichaelScofield changed the title Remove senstive data from copy stmt Using SecretString to store senstive values in copy stmt Apr 24, 2024
@MichaelScofield MichaelScofield added the good first issue Good for newcomers label Apr 24, 2024
@tisonkun
Copy link
Collaborator

I found this issue not quite easy as it may be like.

We hold all the options in WITH and CONNECTION as:

    pub with: OptionMap,
    pub connection: OptionMap,

where:

pub struct OptionMap {
    pub map: HashMap<String, String>,
}

Either we change map: HashMap<String, String> to map: HashMap<String, SecretString>, or we have two inner map, they doesn't sound a good idea.

We now have a function to structurally Display these options:

fn redact_and_sort_options(options: &OptionMap) -> Vec<String> {
    let options = options.as_ref();
    let mut result = Vec::with_capacity(options.len());
    let keys = options.keys().sorted();
    for key in keys {
        if let Some(val) = options.get(key) {
            let redacted = REDACTED_OPTIONS
                .iter()
                .any(|opt| opt.eq_ignore_ascii_case(key));
            if redacted {
                result.push(format!("{key} = '******'"));
            } else {
                result.push(format!("{key} = '{}'", val.escape_default()));
            }
        }
    }
    result
}

We may even implement Display for OptionMap with this functionality, so it's also reliable and can structurally redact the options.

@MichaelScofield
Copy link
Collaborator Author

We can make the sensetive data stored in their own fields, rather then the OptionMap.

@tisonkun
Copy link
Collaborator

tisonkun commented Apr 26, 2024

Then the code to access an option value is somehow awkward. If we insist in trying SecretString, I may suggest:

pub struct OptionMap {
    map: HashMap<String, String>,
    secrets: HashMap<String, SecretString >,
}

And do the merge read within the encapsulation of OptionMap.

@MichaelScofield
Copy link
Collaborator Author

I'm ok with moving all the senstive data to a "secrets" map like that.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C-feature Category Features good first issue Good for newcomers help wanted Extra attention is needed
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants