Skip to content

Commit 8a0c913

Browse files
authored
feat: use privacy-preserving webxdc addresses (#6237)
this PR adds the address to be used by the UI for `window.webxdc.selfAddr` to webxdc-info. UIs need to be changed accordingly and must not use configured_addr any longer. the address is created by sha256(private-key + rfc724_mid) , which results in different addresses for each webxdc, without the option to find out the real address of the user. this also returns the same address for a multi-device-setup - sending totally random self address around might be an alternative, however would require connectivity (both devices may be offline on first start). for existing app, after the change, there will be a new user, resulting eg. in a new highscore, otherwise, things should be mostly fine. this assumption is also important as we might change the thing another time when it comes to multi-transport. ftr, addresses look like `0f187e3f420748b03e3da76543e9a84ecff822687ce7e94f250c04c7c50398bc` now when this is merged, we need to adapt #6230 and file issues for all UI to use `info.selfAddr` closes #6216
1 parent 75e1517 commit 8a0c913

File tree

7 files changed

+42
-2
lines changed

7 files changed

+42
-2
lines changed

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@ serde_json = { workspace = true }
9292
serde_urlencoded = "0.7.1"
9393
serde = { workspace = true, features = ["derive"] }
9494
sha-1 = "0.10"
95+
sha2 = "0.10"
9596
shadowsocks = { version = "1.21.0", default-features = false, features = ["aead-cipher-2022"] }
9697
smallvec = "1.13.2"
9798
strum = "0.26"

deltachat-ffi/deltachat.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4197,6 +4197,7 @@ char* dc_msg_get_webxdc_blob (const dc_msg_t* msg, const char*
41974197
* true if the Webxdc should get full internet access, including Webrtc.
41984198
* currently, this is only true for encrypted Webxdc's in the self chat
41994199
* that have requested internet access in the manifest.
4200+
* - self_addr: address to be used for `window.webxdc.selfAddr` in JS land.
42004201
*
42014202
* @memberof dc_msg_t
42024203
* @param msg The webxdc instance.

deltachat-jsonrpc/src/api/types/webxdc.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@ pub struct WebxdcMessageInfo {
3535
source_code_url: Option<String>,
3636
/// True if full internet access should be granted to the app.
3737
internet_access: bool,
38+
/// Address to be used for `window.webxdc.selfAddr` in JS land.
39+
self_addr: String,
3840
}
3941

4042
impl WebxdcMessageInfo {
@@ -50,6 +52,7 @@ impl WebxdcMessageInfo {
5052
summary,
5153
source_code_url,
5254
internet_access,
55+
self_addr,
5356
} = message.get_webxdc_info(context).await?;
5457

5558
Ok(Self {
@@ -59,6 +62,7 @@ impl WebxdcMessageInfo {
5962
summary: maybe_empty_string_to_option(summary),
6063
source_code_url: maybe_empty_string_to_option(source_code_url),
6164
internet_access,
65+
self_addr,
6266
})
6367
}
6468
}

deltachat-rpc-client/tests/test_webxdc.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ def test_webxdc(acfactory) -> None:
2424
"name": "Chess Board",
2525
"sourceCodeUrl": None,
2626
"summary": None,
27+
"selfAddr": webxdc_info["selfAddr"],
2728
}
2829

2930
status_updates = message.get_webxdc_status_updates()

src/summary.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -289,7 +289,7 @@ mod tests {
289289
use super::*;
290290
use crate::chat::ChatId;
291291
use crate::param::Param;
292-
use crate::test_utils as test;
292+
use crate::test_utils::TestContext;
293293

294294
async fn assert_summary_texts(msg: &Message, ctx: &Context, expected: &str) {
295295
assert_eq!(msg.get_summary_text(ctx).await, expected);
@@ -298,7 +298,7 @@ mod tests {
298298

299299
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
300300
async fn test_get_summary_text() {
301-
let d = test::TestContext::new().await;
301+
let d = TestContext::new_alice().await;
302302
let ctx = &d.ctx;
303303
let chat_id = ChatId::create_for_contact(ctx, ContactId::SELF)
304304
.await

src/webxdc.rs

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,12 +30,14 @@ use lettre_email::PartBuilder;
3030
use rusqlite::OptionalExtension;
3131
use serde::{Deserialize, Serialize};
3232
use serde_json::Value;
33+
use sha2::{Digest, Sha256};
3334

3435
use crate::chat::{self, Chat};
3536
use crate::constants::Chattype;
3637
use crate::contact::ContactId;
3738
use crate::context::Context;
3839
use crate::events::EventType;
40+
use crate::key::{load_self_public_key, DcKey};
3941
use crate::message::{Message, MessageState, MsgId, Viewtype};
4042
use crate::mimefactory::wrapped_base64_encode;
4143
use crate::mimeparser::SystemMessage;
@@ -97,6 +99,9 @@ pub struct WebxdcInfo {
9799
/// It should request access, be encrypted
98100
/// and sent to self for this.
99101
pub internet_access: bool,
102+
103+
/// Address to be used for `window.webxdc.selfAddr` in JS land.
104+
pub self_addr: String,
100105
}
101106

102107
/// Status Update ID.
@@ -872,6 +877,8 @@ impl Message {
872877
&& self.chat_id.is_self_talk(context).await.unwrap_or_default()
873878
&& self.get_showpadlock();
874879

880+
let self_addr = self.get_webxdc_self_addr(context).await?;
881+
875882
Ok(WebxdcInfo {
876883
name: if let Some(name) = manifest.name {
877884
name
@@ -904,8 +911,16 @@ impl Message {
904911
"".to_string()
905912
},
906913
internet_access,
914+
self_addr,
907915
})
908916
}
917+
918+
async fn get_webxdc_self_addr(&self, context: &Context) -> Result<String> {
919+
let fingerprint = load_self_public_key(context).await?.dc_fingerprint().hex();
920+
let data = format!("{}-{}", fingerprint, self.rfc724_mid);
921+
let hash = Sha256::digest(data.as_bytes());
922+
Ok(format!("{:x}", hash))
923+
}
909924
}
910925

911926
#[cfg(test)]
@@ -2288,6 +2303,23 @@ sth_for_the = "future""#
22882303
Ok(())
22892304
}
22902305

2306+
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
2307+
async fn test_get_webxdc_self_addr() -> Result<()> {
2308+
let t = TestContext::new_alice().await;
2309+
let chat_id = create_group_chat(&t, ProtectionStatus::Unprotected, "foo").await?;
2310+
2311+
let instance = send_webxdc_instance(&t, chat_id).await?;
2312+
let info1 = instance.get_webxdc_info(&t).await?;
2313+
let instance = send_webxdc_instance(&t, chat_id).await?;
2314+
let info2 = instance.get_webxdc_info(&t).await?;
2315+
2316+
let real_addr = t.get_primary_self_addr().await?;
2317+
assert!(!info1.self_addr.contains(&real_addr));
2318+
assert_ne!(info1.self_addr, info2.self_addr);
2319+
2320+
Ok(())
2321+
}
2322+
22912323
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
22922324
async fn test_webxdc_info_summary() -> Result<()> {
22932325
let alice = TestContext::new_alice().await;

0 commit comments

Comments
 (0)