@bobfrankston/rmfmail 1.2.313 → 1.2.315
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.commitmsg +15 -20
- package/.llm/trusted-lists.md +5 -1
- package/client/android-bootstrap.bundle.js +19 -0
- package/client/android-bootstrap.bundle.js.map +2 -2
- package/client/app.bundle.js +7 -0
- package/client/app.bundle.js.map +2 -2
- package/client/components/message-viewer.js +16 -0
- package/client/components/message-viewer.js.map +1 -1
- package/client/components/message-viewer.ts +16 -0
- package/npmchanges.md +55 -0
- package/package.json +1 -1
- package/packages/mailx-imap/package-lock.json +2 -2
- package/packages/mailx-imap/package.json +1 -1
- package/packages/mailx-settings/docs/spam-false-positives.md +1 -1
- package/packages/mailx-settings/package.json +1 -1
- package/packages/mailx-store/package.json +1 -1
- package/packages/mailx-store-web/package.json +1 -1
- package/packages/mailx-types/package.json +1 -1
- package/packages/mailx-types/trust.d.ts.map +1 -1
- package/packages/mailx-types/trust.js +45 -0
- package/packages/mailx-types/trust.js.map +1 -1
- package/packages/mailx-types/trust.ts +41 -0
package/.commitmsg
CHANGED
|
@@ -1,22 +1,17 @@
|
|
|
1
|
-
|
|
1
|
+
Self-spoof: the From domain's own SPF or DKIM pass is proof, DMARC verdict or not
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
Follow-up to v1.2.314 (which vetoed the self-spoof finding on a DMARC pass).
|
|
4
|
+
The AMW list (berglist.com) publishes no DMARC policy, so its posts carry
|
|
5
|
+
no dmarc= verdict at all — but iecc.com recorded spf=pass for
|
|
6
|
+
amw-bounces@berglist.com and dkim=pass d=berglist.com, which is the very
|
|
7
|
+
evidence DMARC would have aligned on. The dkim=fail beside them was the
|
|
8
|
+
gmail.com author signature the list broke, and the post was red as a spoof
|
|
9
|
+
of the list's own address (Delivered-To). New alignedPass() in trust.ts:
|
|
10
|
+
a verified signature for the From domain, or an SPF pass for an envelope at
|
|
11
|
+
the From domain, computed as DMARC's relaxed alignment; a forger's pass for
|
|
12
|
+
their own domain clears nothing (tested).
|
|
5
13
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
every proved-list post that stayed red (123 of 1,386 flagged list posts)
|
|
11
|
-
was a phishing or malware URL listing on a throwaway domain that signs
|
|
12
|
-
its own mail, and trusting a list never clears those, so a button there
|
|
13
|
-
would be one that does nothing.
|
|
14
|
-
|
|
15
|
-
Undo: once a list is trusted the chip and banner are gone, so the From
|
|
16
|
-
address's right-click item is now offered on every proved post and reads
|
|
17
|
-
"Stop trusting the ‹List-Id› mailing list" when the list is trusted — the
|
|
18
|
-
toggle the write always was, finally reachable. The action checks that
|
|
19
|
-
the answer went the way it asked and reports otherwise. docs/allowlist.md
|
|
20
|
-
header reworded: the "do not edit" notice is about the .md itself;
|
|
21
|
-
hand-editing allowlist.jsonc is fine and is how a sender or intermediary
|
|
22
|
-
approval is undone until those get an undo of their own.
|
|
14
|
+
Store, last 120 days, messages whose From is their own Delivered-To: 977;
|
|
15
|
+
self-spoof findings 35 before v1.2.314, 20 after it, 15 now. The 15 that
|
|
16
|
+
remain are the sextortion, "failed to deliver", NDA-review and
|
|
17
|
+
document-share phishes the check exists for. mailx-types 0.1.91.
|
package/.llm/trusted-lists.md
CHANGED
|
@@ -40,10 +40,14 @@ tests/trust.test.ts, .commitmsg, TODO.md C165, root version 1.2.311. Then rebuil
|
|
|
40
40
|
## Follow-up 2026-09-09 evening
|
|
41
41
|
- Button beside the chip ("Trust the ‹List-Id› list"), From-menu item now toggles (Stop trusting…), docs reworded re editing allowlist.jsonc. Danger banners keep no list button: 123/123 proved-list danger cases in 120 days were URL phish/malware listings.
|
|
42
42
|
|
|
43
|
+
## Self-spoof false positive (found from Bob's screenshot, 2026-09-09 late)
|
|
44
|
+
- ISOC + berglist posts red as "claims to be from your own address": Delivered-To = list address = From, and selfSpoof took ANY dkim=fail in ANY Authentication-Results as proof of forgery. v1.2.314: DMARC-aligned pass vetoes. Next (v1.2.315): alignedPass() — From domain's own SPF pass or DKIM pass vetoes (relaxed alignment for domains with no DMARC policy). Store: 35 → 20 → 15 findings; the 15 are real phish.
|
|
45
|
+
- Danger banner on a proved-list post now names the list and says right-click From / that trust would not clear it.
|
|
46
|
+
|
|
43
47
|
## Status
|
|
44
48
|
- [x] trust.ts
|
|
45
49
|
- [x] settings/store/service/web
|
|
46
50
|
- [x] client (banner button, From-menu item, chip tooltip)
|
|
47
51
|
- [x] tests pass (tests/trust.test.ts 40/40)
|
|
48
52
|
- [x] docs/TODO/.commitmsg/versions (v1.2.312)
|
|
49
|
-
- [x] rebuild.cmd —
|
|
53
|
+
- [x] rebuild.cmd — v1.2.312 (feature) + v1.2.313 (chip button + undo toggle) published, APKs built. Restart the app to pick up.
|
|
@@ -2267,6 +2267,23 @@ function dkimSigners(input) {
|
|
|
2267
2267
|
}
|
|
2268
2268
|
return out;
|
|
2269
2269
|
}
|
|
2270
|
+
function alignedPass(input) {
|
|
2271
|
+
const fromDomain = (bare(input.fromAddress).split("@")[1] || "").toLowerCase();
|
|
2272
|
+
if (!fromDomain)
|
|
2273
|
+
return "";
|
|
2274
|
+
if (dkimSigners(input).some((d) => sameOrg(d, fromDomain)))
|
|
2275
|
+
return "dkim";
|
|
2276
|
+
const auth = headerAll(input.headerLines, "authentication-results")[0] || "";
|
|
2277
|
+
for (const part of auth.split(";")) {
|
|
2278
|
+
if (!/\bspf=pass\b/i.test(part))
|
|
2279
|
+
continue;
|
|
2280
|
+
const mailfrom = (part.match(/(?:spf|smtp)\.mailfrom=([^\s;,]+)/i)?.[1] || "").toLowerCase();
|
|
2281
|
+
const domain = mailfrom.includes("@") ? mailfrom.split("@")[1] : mailfrom;
|
|
2282
|
+
if (domain && sameOrg(domain, fromDomain))
|
|
2283
|
+
return "spf";
|
|
2284
|
+
}
|
|
2285
|
+
return "";
|
|
2286
|
+
}
|
|
2270
2287
|
function provedIntermediary(input) {
|
|
2271
2288
|
const list = (input.trustedIntermediaries || []).map((d) => (d || "").trim().toLowerCase()).filter(Boolean);
|
|
2272
2289
|
if (!list.length)
|
|
@@ -2483,6 +2500,8 @@ function selfSpoof(input) {
|
|
|
2483
2500
|
const auth = headerAll(input.headerLines, "authentication-results").join(" ; ");
|
|
2484
2501
|
if (!auth)
|
|
2485
2502
|
return null;
|
|
2503
|
+
if (dmarcProof(input).pass || alignedPass(input))
|
|
2504
|
+
return null;
|
|
2486
2505
|
const failed = [
|
|
2487
2506
|
/\bspf=(fail|softfail)\b/i.test(auth) ? "SPF" : "",
|
|
2488
2507
|
/\bdkim=(fail|permerror)\b/i.test(auth) ? "DKIM" : "",
|