From 725f030d3cc0a08495625abd90dc81b7e6070102 Mon Sep 17 00:00:00 2001
From: Mechiel Lukkien <mechiel@ueber.net>
Date: Wed, 1 Nov 2023 18:58:04 +0100
Subject: [PATCH] webmail: add clear marker between message header and body, so
 if html message tries to fake ui elements, it'll be noticed (hopefully)

---
 webmail/webmail.js | 5 ++++-
 webmail/webmail.ts | 5 ++++-
 2 files changed, 8 insertions(+), 2 deletions(-)

diff --git a/webmail/webmail.js b/webmail/webmail.js
index 44e862c..b436684 100644
--- a/webmail/webmail.js
+++ b/webmail/webmail.js
@@ -2865,7 +2865,10 @@ const newMsgView = (miv, msglistView, listMailboxes, possibleLabels, messageLoad
 	let urlType; // text, html, htmlexternal; for opening in new tab/print
 	let msgbuttonElem, msgheaderElem, msgattachmentElem, msgmodeElem;
 	let msgheaderdetailsElem = null; // When full headers are visible, or some headers are requested through settings.
-	const msgmetaElem = dom.div(style({ backgroundColor: '#f8f8f8', borderBottom: '1px solid #ccc', maxHeight: '90%', overflowY: 'auto' }), attr.role('region'), attr.arialabel('Buttons and headers for message'), msgbuttonElem = dom.div(), dom.div(attr.arialive('assertive'), msgheaderElem = dom.table(dom._class('msgheaders'), style({ marginBottom: '1ex', width: '100%' })), msgattachmentElem = dom.div(), msgmodeElem = dom.div()));
+	const msgmetaElem = dom.div(style({ backgroundColor: '#f8f8f8', borderBottom: '5px solid white', maxHeight: '90%', overflowY: 'auto' }), attr.role('region'), attr.arialabel('Buttons and headers for message'), msgbuttonElem = dom.div(), dom.div(attr.arialive('assertive'), msgheaderElem = dom.table(dom._class('msgheaders'), style({ marginBottom: '1ex', width: '100%' })), msgattachmentElem = dom.div(), msgmodeElem = dom.div()), 
+	// Explicit gray line with white border below that separates headers from body, to
+	// prevent HTML messages from faking UI elements.
+	dom.div(style({ height: '2px', backgroundColor: '#ccc' })));
 	const msgscrollElem = dom.div(dom._class('pad', 'yscrollauto'), attr.role('region'), attr.arialabel('Message body'), style({ backgroundColor: 'white' }));
 	const msgcontentElem = dom.div(dom._class('scrollparent'), style({ flexGrow: '1' }));
 	const trashMailboxID = listMailboxes().find(mb => mb.Trash)?.ID;
diff --git a/webmail/webmail.ts b/webmail/webmail.ts
index c621053..17532a8 100644
--- a/webmail/webmail.ts
+++ b/webmail/webmail.ts
@@ -2364,7 +2364,7 @@ const newMsgView = (miv: MsgitemView, msglistView: MsglistView, listMailboxes: l
 	let msgheaderdetailsElem: HTMLElement | null = null // When full headers are visible, or some headers are requested through settings.
 
 	const msgmetaElem = dom.div(
-		style({backgroundColor: '#f8f8f8', borderBottom: '1px solid #ccc', maxHeight: '90%', overflowY: 'auto'}),
+		style({backgroundColor: '#f8f8f8', borderBottom: '5px solid white', maxHeight: '90%', overflowY: 'auto'}),
 		attr.role('region'), attr.arialabel('Buttons and headers for message'),
 		msgbuttonElem=dom.div(),
 		dom.div(
@@ -2373,6 +2373,9 @@ const newMsgView = (miv: MsgitemView, msglistView: MsglistView, listMailboxes: l
 			msgattachmentElem=dom.div(),
 			msgmodeElem=dom.div(),
 		),
+		// Explicit gray line with white border below that separates headers from body, to
+		// prevent HTML messages from faking UI elements.
+		dom.div(style({height: '2px', backgroundColor: '#ccc'})),
 	)
 
 	const msgscrollElem = dom.div(dom._class('pad', 'yscrollauto'),