Browse Source

Escape request values in log messages (#7921)

pull/5910/head 1.37.5
Daniel García 2 weeks ago
committed by GitHub
parent
commit
6ed6921cc2
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 8
      src/api/core/accounts.rs
  2. 6
      src/api/core/ciphers.rs
  3. 33
      src/api/core/organizations.rs
  4. 2
      src/api/icons.rs
  5. 2
      src/api/identity.rs
  6. 2
      src/api/web.rs
  7. 6
      src/auth/send.rs
  8. 2
      src/config.rs
  9. 4
      src/sso.rs

8
src/api/core/accounts.rs

@ -1148,7 +1148,11 @@ async fn post_email_token(data: Json<EmailTokenData>, headers: Headers, conn: Db
error!("Error sending change-email email: {e:#?}"); error!("Error sending change-email email: {e:#?}");
} }
} else { } else {
debug!("Email change request for user ({}) to email ({}) with token ({token})", user.uuid, data.new_email); debug!(
"Email change request for user ({}) to email ({}) with token ({token})",
user.uuid,
data.new_email.escape_debug()
);
} }
user.email_new = Some(data.new_email); user.email_new = Some(data.new_email);
@ -1403,7 +1407,7 @@ async fn password_hint(data: Json<PasswordHintData>, ip: ClientIp, conn: DbConn)
mail::send_password_hint(email, hint).await?; mail::send_password_hint(email, hint).await?;
Ok(()) Ok(())
} else if let Some(hint) = hint { } else if let Some(hint) = hint {
err!(format!("Your password hint is: {hint}")); err_silent!(format!("Your password hint is: {hint}"));
} else { } else {
err!(NO_HINT); err!(NO_HINT);
} }

6
src/api/core/ciphers.rs

@ -458,7 +458,7 @@ pub async fn update_cipher_from_data(
{ {
match NaiveDateTime::parse_from_str(&dt, "%+") { match NaiveDateTime::parse_from_str(&dt, "%+") {
// ISO 8601 format // ISO 8601 format
Err(err) => warn!("Error parsing LastKnownRevisionDate '{dt}': {err}"), Err(err) => warn!("Error parsing LastKnownRevisionDate '{}': {err}", dt.escape_debug()),
Ok(dt) if cipher.updated_at.signed_duration_since(dt).num_seconds() > 1 => { Ok(dt) if cipher.updated_at.signed_duration_since(dt).num_seconds() > 1 => {
err!("The client copy of this cipher is out of date. Resync the client and try again.") err!("The client copy of this cipher is out of date. Resync the client and try again.")
} }
@ -521,7 +521,7 @@ pub async fn update_cipher_from_data(
// A missing attachment means it was removed via an other client. // A missing attachment means it was removed via an other client.
// Also the Desktop Client supports removing attachments and save an update afterwards. // Also the Desktop Client supports removing attachments and save an update afterwards.
// Bitwarden it self ignores these mismatches server side. // Bitwarden it self ignores these mismatches server side.
warn!("Attachment {id} doesn't exist"); warn!("Attachment {} doesn't exist", id.escape_debug());
continue; continue;
}; };
@ -580,7 +580,7 @@ pub async fn update_cipher_from_data(
match data.archived_date { match data.archived_date {
Some(dt_str) => match NaiveDateTime::parse_from_str(&dt_str, "%+") { Some(dt_str) => match NaiveDateTime::parse_from_str(&dt_str, "%+") {
Ok(dt) => cipher.set_archived_at(dt, &headers.user.uuid, conn).await?, Ok(dt) => cipher.set_archived_at(dt, &headers.user.uuid, conn).await?,
Err(err) => warn!("Error parsing ArchivedDate '{dt_str}': {err}"), Err(err) => warn!("Error parsing ArchivedDate '{}': {err}", dt_str.escape_debug()),
}, },
None => cipher.unarchive(&headers.user.uuid, conn).await?, None => cipher.unarchive(&headers.user.uuid, conn).await?,
} }

33
src/api/core/organizations.rs

@ -131,13 +131,16 @@ impl FullCollectionData {
let org_groups = Group::find_by_organization(org_id, conn).await; let org_groups = Group::find_by_organization(org_id, conn).await;
let org_group_ids: HashSet<&GroupId> = org_groups.iter().map(|c| &c.uuid).collect(); let org_group_ids: HashSet<&GroupId> = org_groups.iter().map(|c| &c.uuid).collect();
if let Some(e) = self.groups.iter().find(|g| !org_group_ids.contains(&g.id)) { if let Some(e) = self.groups.iter().find(|g| !org_group_ids.contains(&g.id)) {
err!("Invalid group", format!("Group {} does not belong to organization {}!", e.id, org_id)) err!("Invalid group", format!("Group {} does not belong to organization {}!", e.id.escape_debug(), org_id))
} }
let org_memberships = Membership::find_by_org(org_id, conn).await; let org_memberships = Membership::find_by_org(org_id, conn).await;
let org_membership_ids: HashSet<&MembershipId> = org_memberships.iter().map(|m| &m.uuid).collect(); let org_membership_ids: HashSet<&MembershipId> = org_memberships.iter().map(|m| &m.uuid).collect();
if let Some(e) = self.users.iter().find(|m| !org_membership_ids.contains(&m.id)) { if let Some(e) = self.users.iter().find(|m| !org_membership_ids.contains(&m.id)) {
err!("Invalid member", format!("Member {} does not belong to organization {}!", e.id, org_id)) err!(
"Invalid member",
format!("Member {} does not belong to organization {}!", e.id.escape_debug(), org_id)
)
} }
Ok(()) Ok(())
@ -552,7 +555,7 @@ async fn post_bulk_access_collections(
let org_groups = Group::find_by_organization(&org_id, &conn).await; let org_groups = Group::find_by_organization(&org_id, &conn).await;
let org_group_ids: HashSet<&GroupId> = org_groups.iter().map(|g| &g.uuid).collect(); let org_group_ids: HashSet<&GroupId> = org_groups.iter().map(|g| &g.uuid).collect();
if let Some(g) = data.groups.iter().find(|g| !org_group_ids.contains(&g.id)) { if let Some(g) = data.groups.iter().find(|g| !org_group_ids.contains(&g.id)) {
err!("Invalid group", format!("Group {} does not belong to organization {}!", g.id, org_id)) err!("Invalid group", format!("Group {} does not belong to organization {}!", g.id.escape_debug(), org_id))
} }
for col_id in data.collection_ids { for col_id in data.collection_ids {
@ -975,13 +978,16 @@ impl InviteData {
let org_collections = Collection::find_by_organization(org_id, conn).await; let org_collections = Collection::find_by_organization(org_id, conn).await;
let org_collection_ids: HashSet<&CollectionId> = org_collections.iter().map(|c| &c.uuid).collect(); let org_collection_ids: HashSet<&CollectionId> = org_collections.iter().map(|c| &c.uuid).collect();
if let Some(e) = self.collections.iter().flatten().find(|c| !org_collection_ids.contains(&c.id)) { if let Some(e) = self.collections.iter().flatten().find(|c| !org_collection_ids.contains(&c.id)) {
err!("Invalid collection", format!("Collection {} does not belong to organization {}!", e.id, org_id)) err!(
"Invalid collection",
format!("Collection {} does not belong to organization {}!", e.id.escape_debug(), org_id)
)
} }
let org_groups = Group::find_by_organization(org_id, conn).await; let org_groups = Group::find_by_organization(org_id, conn).await;
let org_group_ids: HashSet<&GroupId> = org_groups.iter().map(|c| &c.uuid).collect(); let org_group_ids: HashSet<&GroupId> = org_groups.iter().map(|c| &c.uuid).collect();
if let Some(e) = self.groups.iter().find(|g| !org_group_ids.contains(g)) { if let Some(e) = self.groups.iter().find(|g| !org_group_ids.contains(g)) {
err!("Invalid group", format!("Group {} does not belong to organization {}!", e, org_id)) err!("Invalid group", format!("Group {} does not belong to organization {}!", e.escape_debug(), org_id))
} }
Ok(()) Ok(())
@ -1157,7 +1163,7 @@ async fn bulk_reinvite_members(
let err_msg = match reinvite_member_impl(&org_id, &member_id, &headers.user.email, &conn).await { let err_msg = match reinvite_member_impl(&org_id, &member_id, &headers.user.email, &conn).await {
Ok(()) => String::new(), Ok(()) => String::new(),
Err(e) => { Err(e) => {
warn!("Unable to reinvite member {member_id}: {e:?}"); warn!("Unable to reinvite member {}: {e:?}", member_id.escape_debug());
e.message().to_owned() e.message().to_owned()
} }
}; };
@ -1333,7 +1339,7 @@ async fn bulk_confirm_invite(
let err_msg = match confirm_invite_impl(&org_id, &member_id, &user_key, &headers, &conn, &nt).await { let err_msg = match confirm_invite_impl(&org_id, &member_id, &user_key, &headers, &conn, &nt).await {
Ok(()) => String::new(), Ok(()) => String::new(),
Err(e) => { Err(e) => {
warn!("Unable to confirm member {member_id}: {e:?}"); warn!("Unable to confirm member {}: {e:?}", member_id.escape_debug());
e.message().to_owned() e.message().to_owned()
} }
}; };
@ -1617,7 +1623,7 @@ async fn bulk_delete_member(
let err_msg = match delete_member_impl(&org_id, &member_id, &headers, &conn, &nt).await { let err_msg = match delete_member_impl(&org_id, &member_id, &headers, &conn, &nt).await {
Ok(()) => String::new(), Ok(()) => String::new(),
Err(e) => { Err(e) => {
warn!("Unable to delete member {member_id}: {e:?}"); warn!("Unable to delete member {}: {e:?}", member_id.escape_debug());
e.message().to_owned() e.message().to_owned()
} }
}; };
@ -2286,7 +2292,7 @@ async fn bulk_revoke_members(
let err_msg = match revoke_member_impl(&org_id, &member_id, &headers, &conn).await { let err_msg = match revoke_member_impl(&org_id, &member_id, &headers, &conn).await {
Ok(()) => String::new(), Ok(()) => String::new(),
Err(e) => { Err(e) => {
warn!("Unable to revoke member {member_id}: {e:?}"); warn!("Unable to revoke member {}: {e:?}", member_id.escape_debug());
e.message().to_owned() e.message().to_owned()
} }
}; };
@ -2392,7 +2398,7 @@ async fn bulk_restore_members(
let err_msg = match restore_member_impl(&org_id, &member_id, &headers, &conn).await { let err_msg = match restore_member_impl(&org_id, &member_id, &headers, &conn).await {
Ok(()) => String::new(), Ok(()) => String::new(),
Err(e) => { Err(e) => {
warn!("Unable to restore member {member_id}: {e:?}"); warn!("Unable to restore member {}: {e:?}", member_id.escape_debug());
e.message().to_owned() e.message().to_owned()
} }
}; };
@ -2547,13 +2553,16 @@ impl GroupRequest {
let org_collections = Collection::find_by_organization(org_id, conn).await; let org_collections = Collection::find_by_organization(org_id, conn).await;
let org_collection_ids: HashSet<&CollectionId> = org_collections.iter().map(|c| &c.uuid).collect(); let org_collection_ids: HashSet<&CollectionId> = org_collections.iter().map(|c| &c.uuid).collect();
if let Some(e) = self.collections.iter().find(|c| !org_collection_ids.contains(&c.id)) { if let Some(e) = self.collections.iter().find(|c| !org_collection_ids.contains(&c.id)) {
err!("Invalid collection", format!("Collection {} does not belong to organization {}!", e.id, org_id)) err!(
"Invalid collection",
format!("Collection {} does not belong to organization {}!", e.id.escape_debug(), org_id)
)
} }
let org_memberships = Membership::find_by_org(org_id, conn).await; let org_memberships = Membership::find_by_org(org_id, conn).await;
let org_membership_ids: HashSet<&MembershipId> = org_memberships.iter().map(|m| &m.uuid).collect(); let org_membership_ids: HashSet<&MembershipId> = org_memberships.iter().map(|m| &m.uuid).collect();
if let Some(e) = self.users.iter().find(|m| !org_membership_ids.contains(m)) { if let Some(e) = self.users.iter().find(|m| !org_membership_ids.contains(m)) {
err!("Invalid member", format!("Member {} does not belong to organization {}!", e, org_id)) err!("Invalid member", format!("Member {} does not belong to organization {}!", e.escape_debug(), org_id))
} }
Ok(()) Ok(())

2
src/api/icons.rs

@ -264,7 +264,7 @@ fn get_favicons_node(dom: Tokenizer<StringReader<'_>, FaviconEmitter>, icons: &m
TAG_BASE => { TAG_BASE => {
base_url = if let Some(href) = token.tag.attributes.get(ATTR_HREF) { base_url = if let Some(href) = token.tag.attributes.get(ATTR_HREF) {
let href = std::str::from_utf8(href).unwrap_or_default(); let href = std::str::from_utf8(href).unwrap_or_default();
debug!("Found base href: {href}"); debug!("Found base href: {}", href.escape_debug());
match base_url.join(href) { match base_url.join(href) {
Ok(inner_url) => inner_url, Ok(inner_url) => inner_url,
_ => continue, _ => continue,

2
src/api/identity.rs

@ -112,7 +112,7 @@ async fn login(data: Form<ConnectData>, client_header: ClientHeaders, conn: DbCo
.await?; .await?;
Ok(Json(tokens.to_json())) Ok(Json(tokens.to_json()))
} }
t => err!("Invalid type", t), t => err!("Invalid type", t.escape_debug().to_string()),
}; };
if let Some(user_id) = user_id { if let Some(user_id) = user_id {

2
src/api/web.rs

@ -332,6 +332,6 @@ pub fn static_files(filename: &str) -> Result<EtagCached<&'static [u8]>, Error>
if let Some(file) = STATIC_FILES.get(filename) { if let Some(file) = STATIC_FILES.get(filename) {
Ok(EtagCached::new(file.bytes, file.content_type.clone(), &file.etag)) Ok(EtagCached::new(file.bytes, file.content_type.clone(), &file.etag))
} else { } else {
err!(format!("Static file not found: {filename}")) err!(format!("Static file not found: {}", filename.escape_debug()))
} }
} }

6
src/auth/send.rs

@ -72,7 +72,11 @@ impl SendTokens {
conn: &DbConn, conn: &DbConn,
) -> ApiResult<SendTokens> { ) -> ApiResult<SendTokens> {
let Some(send_id) = Self::as_send_id(access_id) else { let Some(send_id) = Self::as_send_id(access_id) else {
return Self::invalid_error(&format!("Can't convert {access_id}"), "send_id_invalid", false); return Self::invalid_error(
&format!("Can't convert {}", access_id.escape_debug()),
"send_id_invalid",
false,
);
}; };
let Some(send) = Send::find_by_uuid(&send_id, conn).await else { let Some(send) = Send::find_by_uuid(&send_id, conn).await else {

2
src/config.rs

@ -1616,7 +1616,7 @@ impl Config {
pub fn is_email_domain_allowed(&self, email: &str) -> bool { pub fn is_email_domain_allowed(&self, email: &str) -> bool {
let e: Vec<&str> = email.rsplitn(2, '@').collect(); let e: Vec<&str> = email.rsplitn(2, '@').collect();
if e.len() != 2 || e[0].is_empty() || e[1].is_empty() { if e.len() != 2 || e[0].is_empty() || e[1].is_empty() {
warn!("Failed to parse email address '{email}'"); warn!("Failed to parse email address '{}'", email.escape_debug());
return false; return false;
} }
let email_domain = e[0].to_lowercase(); let email_domain = e[0].to_lowercase();

4
src/sso.rs

@ -266,8 +266,8 @@ pub async fn exchange_code(
(_, Some(re)) => { (_, Some(re)) => {
let error_msg = format!( let error_msg = format!(
"SSO authorization failed: {}, {}", "SSO authorization failed: {}, {}",
re.error, re.error.escape_debug(),
re.error_description.as_ref().unwrap_or(&String::new()) re.error_description.as_deref().unwrap_or_default().escape_debug()
); );
sso_auth.delete(conn).await?; sso_auth.delete(conn).await?;
err!(error_msg); err!(error_msg);

Loading…
Cancel
Save