lo48576 / iri-string

String types for URIs/IRIs.
Apache License 2.0
15 stars 3 forks source link

Hide password by default from formatted printing #25

Closed lo48576 closed 2 years ago

lo48576 commented 2 years ago

Applications should not render as clear text any data after the first colon (":") character found within a userinfo subcomponent unless the data after the colon is the empty string (indicating no password).

--- RFC 3986 section 3.2.1. User Information

According to this, println!("{}", uri); or such "usual" formatting should hide the password part of the userinfo component, unless explicitly specified. To see full userinfo, uri.display_unsecure() or uri.display_secrets() would have to be provided.

lo48576 commented 2 years ago

This doesn't change API breakingly (i.e. downstream code compilable with the previous verisons are still compilable after this change), but this will break some kind of codes semantically. Because of this, I treat this as a breaking change.

lo48576 commented 2 years ago

Is it enough if Display writes https://user@example.com/ and Debug writes https://user:pass@example.com/ (or <https://user:pass@example.com/>)? I think this may still have a risk that the user unintentionally prints sensitive information into logging file, error page, or something like that. Debug can be used indirectly through derive(Debug), so allowing Debug to print credentials would be bad.

lo48576 commented 2 years ago

I decided not to hide the password by default. Newly added {BorrowedIri}::mask_password() method lets users hide or replace the password part.

The reason not to change the default is, some types requires core::fmt::Display to write the raw IRI including the password part, since strings generation by builder and proxy types are built on core::fmt::Display trait. If some types hides the password and some others don't, it will confuse users and may become the cause of the vulnerability. So I decided to let core::fmt::Display write the raw (uncensored) values anytime, and require users to explicitly mask IRIs.

Explicit masking provides useful features, like replacing password instead of removing. (For example, it is possible to write http://user:password@example.com as http://user:${password}@example.com or http://user:********@example.com.)