Hi everyone, I have noticed that some recent versions of Delta Chat started to spoof more than just the subject header when sending OpenPGP-encrypted messages. From what I saw, they mask at least the following three headers:
1. Date -- the outer header contains a fictitious date while the protected header contains the real date. 2. To -- the outer header is set to `"hidden-recipients": ;` while the protected header contains the full display name and email address of the recipient. 3. From -- the outer header contains only the email address while the protected header contains both the email address and the display name of the sender. To my eyes, these ways of masking protected headers look like they should be valid. I have not yet gotten around to looking any deeper into how protected headers are implemented in notmuch. However, I attach a patch with additional tests for the three cases described above as a form of executable bug report. I would not be surprised if future versions of Delta Chat started to spoof even more unprotected headers, like References, In-Reply-To, or even Message-ID. If anyone fixes the issues described above, they might want to check if they can make the implementation generic enough to cover such cases as well. Best Frank
>From 422f184a93f677242c01837ee4666ba6605b70b4 Mon Sep 17 00:00:00 2001 From: Frank Seifferth <[email protected]> Date: Thu, 18 Dec 2025 17:41:07 +0100 Subject: [PATCH] Add more test cases for protected headers Some versions of Delta Chat recently started to send spoofed headers that are overridden by the protected headers of OpenPGP-encrypted messages. Currently, notmuch uses the spoofed headers rather than the real ones, with the subject being the sole exception. This commit adds test cases for the following three headers: Date, To, and From. The example messages were modelled after what Delta Chat produces, which (in my opinion) look like it should be valid. --- test/T356-protected-headers.sh | 70 ++++++++++++++++++- .../protected-headers/spoofed-date.eml | 28 ++++++++ .../protected-headers/spoofed-recipient.eml | 28 ++++++++ .../protected-headers/spoofed-sender.eml | 29 ++++++++ 4 files changed, 154 insertions(+), 1 deletion(-) create mode 100644 test/corpora/protected-headers/spoofed-date.eml create mode 100644 test/corpora/protected-headers/spoofed-recipient.eml create mode 100644 test/corpora/protected-headers/spoofed-sender.eml diff --git a/test/T356-protected-headers.sh b/test/T356-protected-headers.sh index 9f640331..712c099d 100755 --- a/test/T356-protected-headers.sh +++ b/test/T356-protected-headers.sh @@ -24,6 +24,36 @@ test_json_nodes <<<"$output" \ 'crypto:[0][0][0]["crypto"]={"decrypted": {"status": "full", "header-mask": {"Subject": "Subject Unavailable"}}}' \ 'subject:[0][0][0]["headers"]["Subject"]="This is a protected header"' +test_begin_subtest "verify spoofed date is shown without decryption" +output=$(notmuch show --format=json id:[email protected]) +test_json_nodes <<<"$output" \ + 'subject:[0][0][0]["headers"]["Date"]="Sat, 01 Jan 2000 12:00:00 +0000"' + +test_begin_subtest "verify real date is shown with decryption" +output=$(notmuch show --decrypt=true --format=json id:[email protected]) +test_json_nodes <<<"$output" \ + 'subject:[0][0][0]["headers"]["Date"]="Wed, 16 Dec 2015 17:19:18 +0100"' + +test_begin_subtest "verify spoofed recipient is shown without decryption" +output=$(notmuch show --format=json id:[email protected]) +test_json_nodes <<<"$output" \ + 'subject:[0][0][0]["headers"]["To"]="undisclosed-recipients: ;"' + +test_begin_subtest "verify real recipient is shown with decryption" +output=$(notmuch show --decrypt=true --format=json id:[email protected]) +test_json_nodes <<<"$output" \ + 'subject:[0][0][0]["headers"]["To"]="Notmuch Test Suite <[email protected]>"' + +test_begin_subtest "verify spoofed sender is shown without decryption" +output=$(notmuch show --format=json id:[email protected]) +test_json_nodes <<<"$output" \ + 'subject:[0][0][0]["headers"]["From"]="[email protected]"' + +test_begin_subtest "verify real sender is shown with decryption" +output=$(notmuch show --decrypt=true --format=json id:[email protected]) +test_json_nodes <<<"$output" \ + 'subject:[0][0][0]["headers"]["From"]="Notmuch Test Suite <[email protected]>"' + test_begin_subtest "when no external header is present, show masked subject as null" output=$(notmuch show --decrypt=true --format=json id:[email protected]) test_json_nodes <<<"$output" \ @@ -87,7 +117,7 @@ test_begin_subtest "protected subject is not indexed by default" output=$(notmuch search --output=messages 'subject:"This is a protected header"') test_expect_equal "$output" '' -test_begin_subtest "reindex message with protected header" +test_begin_subtest "reindex message with protected subject" test_expect_success 'notmuch reindex --decrypt=true id:[email protected]' test_begin_subtest "protected subject is indexed when cleartext is indexed" @@ -105,6 +135,41 @@ test_json_nodes <<<"$output" \ 'subject:["original"]["headers"]["Subject"]="This is a protected header"' \ 'reply-subject:["reply-headers"]["Subject"]="Re: Subject Unavailable"' +test_begin_subtest "spoofed date is used when cleartext is not indexed" +output=$(notmuch search --output=messages 'id:[email protected] and date:2000-01-01') +test_expect_equal "$output" 'id:[email protected]' + +test_begin_subtest "real date is masked when cleartext is not indexed" +output=$(notmuch search --output=messages 'id:[email protected] and date:2015-12-16') +test_expect_equal "$output" '' + +test_begin_subtest "real recipient is masked when cleartext is not indexed" +output=$(notmuch search --output=messages 'id:[email protected] and to:"Notmuch Test Suite"') +test_expect_equal "$output" '' + +test_begin_subtest "real sender is masked when cleartext is not indexed" +output=$(notmuch search --output=messages 'id:[email protected] and from:"Notmuch Test Suite"') +test_expect_equal "$output" '' + +test_begin_subtest "reindex messages with spoofed headers" +test_expect_success 'notmuch reindex --decrypt=true id:[email protected] or id:[email protected] or id:[email protected]' + +test_begin_subtest "spoofed date is ignored when cleartext is indexed" +output=$(notmuch search --output=messages 'id:[email protected] and date:2000-01-01') +test_expect_equal "$output" '' + +test_begin_subtest "real date is used when cleartext is indexed" +output=$(notmuch search --output=messages 'id:[email protected] and date:2015-12-16') +test_expect_equal "$output" 'id:[email protected]' + +test_begin_subtest "real recipient is used when cleartext is indexed" +output=$(notmuch search --output=messages 'id:[email protected] and to:"Notmuch Test Suite"') +test_expect_equal "$output" 'id:[email protected]' + +test_begin_subtest "real sender is used when cleartext is indexed" +output=$(notmuch search --output=messages 'id:[email protected] and from:"Notmuch Test Suite"') +test_expect_equal "$output" 'id:[email protected]' + test_begin_subtest "verify correct protected header when submessage exists" output=$(notmuch show --decrypt=true --format=json id:encrypted-message-with-forwarded-attachm...@crypto.notmuchmail.org) test_json_nodes <<<"$output" \ @@ -134,6 +199,9 @@ test_expect_equal "$output" 'id:[email protected] id:[email protected] id:[email protected] id:[email protected] +id:[email protected] +id:[email protected] +id:[email protected] id:[email protected]' test_begin_subtest "when rendering protected headers, avoid rendering legacy-display part" diff --git a/test/corpora/protected-headers/spoofed-date.eml b/test/corpora/protected-headers/spoofed-date.eml new file mode 100644 index 00000000..b3e5bb5a --- /dev/null +++ b/test/corpora/protected-headers/spoofed-date.eml @@ -0,0 +1,28 @@ +From: [email protected] +To: [email protected] +Subject: Subject Unavailable +Date: Sat, 01 Jan 2000 12:00:00 +0000 +Message-ID: <[email protected]> +MIME-Version: 1.0 +Content-Type: multipart/encrypted; boundary="=-=-="; + protocol="application/pgp-encrypted" + +--=-=-= +Content-Type: application/pgp-encrypted + +Version: 1 + +--=-=-= +Content-Type: application/octet-stream + +-----BEGIN PGP MESSAGE----- + +hF4DHXHP849rSK8SAQdALxucRFN71JbLt2GfNFt2/YrBvrshI8tGn7IzlxdE+1sw ++Pu7X4CisgRLrNP5NrkCeXd3qtdBL1oCp7Q8CE1MzagVZb3tGE9tdGjHqOHSUIcg +0rsBt1bR4Vdunh5kgzfYVV3JqdtgQlZXF/AUrkB8LatxZ6nA9V0t/DC63dh6gUsJ +EnbjAZq9z/k5Tjgi52+gXarl62cJQp7YSFLU2GgHCOjUMLugNPpr9J3YRtN9u7Np +fLenbcQynXRWY0MNp+vRzWoVPi2g4A4J+L+LRKmChX/Ni6gqEU1ksXnhkX9+dZXs +J4T6ixs1IyJxfyQCmA1bbi9exkORLdE7ZyxgYC3kSWUzivjwz68PdHUqitE+ +=XRi1 +-----END PGP MESSAGE----- +--=-=-=-- diff --git a/test/corpora/protected-headers/spoofed-recipient.eml b/test/corpora/protected-headers/spoofed-recipient.eml new file mode 100644 index 00000000..f9d47c57 --- /dev/null +++ b/test/corpora/protected-headers/spoofed-recipient.eml @@ -0,0 +1,28 @@ +From: [email protected] +To: undisclosed-recipients: ; +Subject: Subject Unavailable +Date: Sat, 01 Jan 2000 12:00:00 +0000 +Message-ID: <[email protected]> +MIME-Version: 1.0 +Content-Type: multipart/encrypted; boundary="=-=-="; + protocol="application/pgp-encrypted" + +--=-=-= +Content-Type: application/pgp-encrypted + +Version: 1 + +--=-=-= +Content-Type: application/octet-stream + +-----BEGIN PGP MESSAGE----- + +hF4DHXHP849rSK8SAQdA15+QCv0bg+6LKzXtfj4pPyrOwkzIhCPgLd3aeMnv3WMw +KcOKlfdgmEtI92AZFCpDErTceKpcTzVz2m9vaR3ZLIntf4Db8P/KPVTLeJla9Wy0 +0r4BEuH4GwCq/rM889/funOJBIm/amlNEAbOicBR9QJzqAkvQ1i9SsrAuA/MFA7S +/sH3RrNT0x00UHh6i2Ho5B+GgJFBpYyijZb6dGXcMt8jMrhM/D3hQvu2VLL72h6z +cHjqEIxYrgCXcmMKGzXFpv0WLYXVbe/BU6tcTUqzcQtRXQAImv3WQXmTx0ZXHxe0 +y4DkxxrdLMS4ogKp6iPCtqIjGV6wrBRVlcFGTh+1gmhYiAviKixx03XfRCw7YZTj +=vcs2 +-----END PGP MESSAGE----- +--=-=-=-- diff --git a/test/corpora/protected-headers/spoofed-sender.eml b/test/corpora/protected-headers/spoofed-sender.eml new file mode 100644 index 00000000..ed1d2595 --- /dev/null +++ b/test/corpora/protected-headers/spoofed-sender.eml @@ -0,0 +1,29 @@ +From: [email protected] +To: undisclosed-recipients: ; +Subject: Subject Unavailable +Date: Sat, 01 Jan 2000 12:00:00 +0000 +Message-ID: <[email protected]> +MIME-Version: 1.0 +Content-Type: multipart/encrypted; boundary="=-=-="; + protocol="application/pgp-encrypted" + +--=-=-= +Content-Type: application/pgp-encrypted + +Version: 1 + +--=-=-= +Content-Type: application/octet-stream + +-----BEGIN PGP MESSAGE----- + +hF4DHXHP849rSK8SAQdA21XV8GyULURScZxf9wBJs5j+5z3OvXJYTKVVURbUVVAw +sJL+xsbZY24IkCDqX6YEY/iCZgnwJMXWkgtkiapQnLhGj9NOiBa3++iuzZVJ9/26 +0sAJAZCrLPqeCBtB3WveXXrY974CFYE6q1hp27bye5hY0mNDxudEEUpfMA0t6dFV +BhzYCkdIbZSwYglr8JM4vaHKpeMT3RgiANm9IxG4vKieLS8rFzJ54Q6EPIpROLkd +WDpoCtfXTHj9vvr+Vx2eLdURCsdcA4Kjj4Xdujz04p5yq3UcCx/5Ml2vwKZJTVzO +41mTVzkx52Y4iDgOupjdvAy0UIkowj/gXzhcVOL/0VRG4MMelQ3raiuNiOP19es+ +id0ZmRgEoEB0TsrY +=DZBa +-----END PGP MESSAGE----- +--=-=-=-- -- 2.39.5
_______________________________________________ notmuch mailing list -- [email protected] To unsubscribe send an email to [email protected]
