diff options
author | Mathijs van Veluw <[email protected]> | 2024-10-13 20:25:09 +0200 |
---|---|---|
committer | GitHub <[email protected]> | 2024-10-13 20:25:09 +0200 |
commit | 49c5dec9b6c1899f8fc5ad3cff0ddc09cecf71c5 (patch) | |
tree | 7e7fb9ab2e4d0c3c1ada6379cecfe00c352cd628 | |
parent | cd195ff24339056bc5246bd5ee9106379e7fb6e6 (diff) | |
download | vaultwarden-49c5dec9b6c1899f8fc5ad3cff0ddc09cecf71c5.tar.gz vaultwarden-49c5dec9b6c1899f8fc5ad3cff0ddc09cecf71c5.zip |
Fix iOS sync by converting field types to int (#5081)
It seems the iOS clients are not able to handle the `type` key within the `fields` array when they are of the type string.
All other clients seem to handle this just fine though.
This PR fixes this by validating it is a number, if this is not the case, try to convert the string to a number, or return the default of `1`.
`1` is used as this is the type `hidden` and should prevent accidental data disclosure.
Fixes #5069
Possibly Fixes #5016
Possibly Fixes #5002
Signed-off-by: BlackDex <[email protected]>
-rw-r--r-- | src/db/models/cipher.rs | 24 |
1 files changed, 22 insertions, 2 deletions
diff --git a/src/db/models/cipher.rs b/src/db/models/cipher.rs index a445e5c5..9dc9cba5 100644 --- a/src/db/models/cipher.rs +++ b/src/db/models/cipher.rs @@ -176,7 +176,27 @@ impl Cipher { .inspect_err(|e| warn!("Error parsing fields {e:?} for {}", self.uuid)) .ok() }) - .map(|d| d.into_iter().map(|d| d.data).collect()) + .map(|d| { + d.into_iter() + .map(|mut f| { + // Check if the `type` key is a number, strings break some clients + // The fallback type is the hidden type `1`. this should prevent accidental data disclosure + // If not try to convert the string value to a number and fallback to `1` + // If it is both not a number and not a string, fallback to `1` + match f.data.get("type") { + Some(t) if t.is_number() => {} + Some(t) if t.is_string() => { + let type_num = &t.as_str().unwrap_or("0").parse::<u8>().unwrap_or(1); + f.data["type"] = json!(type_num); + } + _ => { + f.data["type"] = json!(1); + } + } + f.data + }) + .collect() + }) .unwrap_or_default(); let password_history_json: Vec<_> = self @@ -244,7 +264,7 @@ impl Cipher { // NOTE: This was marked as *Backwards Compatibility Code*, but as of January 2021 this is still being used by upstream // data_json should always contain the following keys with every atype - data_json["fields"] = Value::Array(fields_json.clone()); + data_json["fields"] = json!([fields_json]); data_json["name"] = json!(self.name); data_json["notes"] = json!(self.notes); data_json["passwordHistory"] = Value::Array(password_history_json.clone()); |