Escape request values in log messages (#7921)

This commit is contained in:
Daniel García authored and GitHub committed 2026-11-01 22:38:18 +01:00
1 parent 5d870b796f
commit 6ed6921cc2
9 files changed
+41 -24

No files matched your search

+6 -2
View File
@@ -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);
} }
+3 -3
View File
@@ -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?,
} }
+21 -12
View File
@@ -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(())
+1 -1
View File
@@ -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,
+1 -1
View File
@@ -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 {
+1 -1
View File
@@ -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()))
} }
} }
+5 -1
View File
@@ -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 {
+1 -1
View File
@@ -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();
+2 -2
View File
@@ -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);