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

std::fmt::Display implementation on error shapes does not honor the sensitive trait #1743

Closed
david-perez opened this issue Sep 19, 2022 · 4 comments
Assignees
Labels
bug Something isn't working good first issue Good for newcomers

Comments

@david-perez
Copy link
Contributor

This model:

@error("client")
structure ErrorWithMessage {
    message: SensitiveString
}

@sensitive
string SensitiveString

generates:

#[allow(missing_docs)] // documentation missing in model
#[derive(std::clone::Clone, std::cmp::PartialEq)]
pub struct ErrorWithMessage {
    #[allow(missing_docs)] // documentation missing in model
    #[doc(hidden)]
    pub message: std::option::Option<std::string::String>,
}
impl std::fmt::Debug for ErrorWithMessage {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        let mut formatter = f.debug_struct("ErrorWithMessage");
        formatter.field("message", &"*** Sensitive Data Redacted ***");
        formatter.finish()
    }
}
impl ErrorWithMessage {
    /// Returns the error message.
    pub fn message(&self) -> std::option::Option<&str> {
        self.message.as_deref()
    }
    #[doc(hidden)]
    /// Returns the error name.
    pub fn name(&self) -> &'static str {
        "ErrorWithMessage"
    }
}
impl std::fmt::Display for ErrorWithMessage {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        write!(f, "ErrorWithMessage")?;
        if let Some(inner_1) = &self.message {
            write!(f, ": {}", inner_1)?;
        }
        Ok(())
    }
}
impl std::error::Error for ErrorWithMessage {}
...

Note how the Debug implementation honors the sensitive trait, but the Display implementation does not.

The code that generates the Debug implementation is:

https://github.com/awslabs/smithy-rs/blob/ffafbec885c1e83a460fed38fc98119bb63d0439/codegen-client/src/main/kotlin/software/amazon/smithy/rust/codegen/client/smithy/generators/StructureGenerator.kt#L108-L127

The code that generates the Display implementation is:

https://github.com/awslabs/smithy-rs/blob/ffafbec885c1e83a460fed38fc98119bb63d0439/codegen-client/src/main/kotlin/software/amazon/smithy/rust/codegen/client/smithy/generators/error/TopLevelErrorGenerator.kt#L82-L93

@david-perez david-perez added bug Something isn't working good first issue Good for newcomers labels Sep 19, 2022
@jjant jjant self-assigned this Sep 28, 2022
@hlbarber
Copy link
Contributor

hlbarber commented Sep 28, 2022

During implementation of Logging in the Presence of Sensitive Data, I added https://github.com/awslabs/smithy-rs/blob/dcfb85578ef10e8d4fcb037c2fcf7d2a5e879f70/rust-runtime/aws-smithy-http-server/src/instrumentation/sensitivity/sensitive.rs.

Reusing this machinery might be a good idea because:

This changes the proposed implementation very slightly:

impl std::fmt::Debug for ErrorWithMessage {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        let mut formatter = f.debug_struct("ErrorWithMessage");
        formatter.field("message", Sensitive(self.message));
        formatter.finish()
    }
}

A similar argument can be made for going back and editing this implementation too #229.

@jjant
Copy link
Contributor

jjant commented Sep 28, 2022

I think the current implementation would only make sense if the @sensitive trait could only be used in member shapes:

structure ErrorWithMessage {
    @sensitive
    message: String
}

That way you could only worry about the field being sensitive in the context of the encompassing ErrorWithMessage struct (like we do in the Debug/Display impls for it).

But if we have a plain type like:

@sensitive
string SensitiveString

That should be sensitive regardless of where it's used, but currently you could do:

println!("{}", error_with_message.message/* or .unwrap() */)

And have it logged.


From what I can see, the only way to fix it would be to generate a Sensitive<String> everywhere SensitiveString is used in the Smithy model.

@jjant
Copy link
Contributor

jjant commented Oct 7, 2022

Done in #1802.

@jjant jjant closed this as completed Oct 7, 2022
@david-perez
Copy link
Contributor Author

@jjant We should create a new issue with your findings in #1743 (comment) about whether we should wrap Strings to make their Display implementation honor sensitive; we still need to (eventually) make a decision on that.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working good first issue Good for newcomers
Projects
None yet
Development

No branches or pull requests

3 participants