From 4f1b87a34618b5679060311973a1fed7ac086a01 Mon Sep 17 00:00:00 2001 From: granlem Date: Tue, 10 Mar 2026 18:04:33 +0100 Subject: [PATCH 1/4] Fix: Require isTrusted for button actions (real click) --- js/tooltip.js | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/js/tooltip.js b/js/tooltip.js index c068fe5..767fa75 100644 --- a/js/tooltip.js +++ b/js/tooltip.js @@ -4,6 +4,7 @@ var timerArr = []; * Returns the HTML skeleton for a tooltip */ function getTooltipHTML(securityStatus, httpsAvailable, fieldType) { + let textObj = getTooltipText(securityStatus, httpsAvailable, fieldType); return '' + textObj.tooltipSummary + '' + @@ -142,7 +143,7 @@ function assignText(tooltip, url, securityStatus, fieldType, formURLObj, qtipID) $(tooltip.find(".http-warning")).hide(); $(tooltip.find(".https")).show(); - // Data is transferred to another server + // Data is transferred to another server if (securityStatus[3] == 0) { passSecFormURLTextElem.html(chrome.i18n.getMessage("formURLInfoText" + fieldTypeForText)); let formURLStr = formURLObj.url; @@ -179,6 +180,7 @@ function addFunctionalityForTooltipElements(tooltip, securityStatus, fieldType, [exceptionButton, closeButton].forEach(function (element) { element.on("mousedown", function (event) { + if (e.originalEvent && !e.originalEvent.isTrusted) { return; } // Deny trigger using JavaScript (not by actual the mouse) // prevent input element losing focus event.stopImmediatePropagation(); event.preventDefault(); @@ -186,6 +188,7 @@ function addFunctionalityForTooltipElements(tooltip, securityStatus, fieldType, }); // Close Button Event closeButton.on("mouseup", function (event) { + if (e.originalEvent && !e.originalEvent.isTrusted) { return; } // Deny trigger using JavaScript (not by actual the mouse) $(element).qtip("hide"); }); @@ -214,14 +217,16 @@ function addFunctionalityForTooltipElements(tooltip, securityStatus, fieldType, switch (siteUseHttps + formUseHttps + sameDomain) { // site protocol is https case "111": - exceptionButton.on("mouseup", function () { - passSecTooltip.addUserException(securityStatus, passSec.domain, "userTrustedDomains", false); + exceptionButton.on("mouseup", function (e) { + if (e.originalEvent && !e.originalEvent.isTrusted) { return; } // Deny trigger using JavaScript (not by actual the mouse) + passSecTooltip.addUserException(securityStatus, passSec.domain, "userTrustedDomains", false); }); break; // site protocol is https case "100": case "110": case "101": - exceptionButton.on("mouseup", function () { + exceptionButton.on("mouseup", function (e) { + if (e.originalEvent && !e.originalEvent.isTrusted) { return; } // Deny trigger using JavaScript (not by actual the mouse) let exception = passSecTooltip.createUserException(passSec.websiteProtocol, passSec.domain, formURLObj.protocol, formURLObj.domain); $(element).qtip("hide"); openConfirmAddingExceptionWithAnomalyDialog("confirmAddingHttpException", securityStatus, exception, "userExceptions"); @@ -230,7 +235,8 @@ function addFunctionalityForTooltipElements(tooltip, securityStatus, fieldType, break; // site protocol is http case "000": case "001": case "010": case "011": - exceptionButton.on("mouseup", function () { + exceptionButton.on("mouseup", function (e) { + if (e.originalEvent && !e.originalEvent.isTrusted) { return; } // Deny trigger using JavaScript (not by actual the mouse) let exception = passSecTooltip.createUserException(passSec.websiteProtocol, passSec.domain, formURLObj.protocol, formURLObj.domain); $(element).qtip("hide"); openConfirmAddingExceptionWithAnomalyDialog("confirmAddingHttpException", securityStatus, exception, "userExceptions"); @@ -239,7 +245,8 @@ function addFunctionalityForTooltipElements(tooltip, securityStatus, fieldType, if (passSec.httpsAvailable) { // "Switch to HTTPS" Event let changeToHttpsButton = $(tooltip.find("#passSecButtonSecureMode")[0]); - changeToHttpsButton.on("mousedown", function () { + changeToHttpsButton.on("mousedown", function (e) { + if (e.originalEvent && !e.originalEvent.isTrusted) { return; } // Deny trigger using JavaScript (not by actual the mouse) chrome.storage.local.get("redirects", function (item) { let redirectPattern = "http://*." + passSec.domain + "/*"; if (!item.redirects.includes(redirectPattern)) { @@ -350,4 +357,4 @@ function openConfirmAddingExceptionWithAnomalyDialog(message, securityStatus, ex useBootstrap: false, boxWidth: "40%" }); -} \ No newline at end of file +} From f4976728b836134d1d8397c932189a3c70f3041a Mon Sep 17 00:00:00 2001 From: granlem Date: Tue, 10 Mar 2026 18:18:23 +0100 Subject: [PATCH 2/4] Fix: Filter by :read-write Fixes #18 Related: #19 --- js/input-field.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/js/input-field.js b/js/input-field.js index 98166a1..3e455db 100644 --- a/js/input-field.js +++ b/js/input-field.js @@ -7,7 +7,7 @@ function processInputs(storage) { // exclude input elements from analysis that cannot be used to input meaningful data (type submit|reset|button|image) // and that cannot be styled appropriately (type radio|checkbox) - $('input:not([type=submit],[type=reset],[type=button],[type=image],[type=radio],[type=checkbox]),textarea').each(function (index) { + $('input:not([type=submit],[type=reset],[type=button],[type=image],[type=radio],[type=checkbox]):read-write,textarea:read-write').each(function (index) { let fieldType = determineFieldType(this, storage); if (typeof fieldType !== "undefined") { let securityStatus = getSecurityStatus(storage, this.form); From 9685d19cdfe5f82d564ff66f51cf73bf20a85217 Mon Sep 17 00:00:00 2001 From: granlem Date: Wed, 11 Mar 2026 14:01:02 +0100 Subject: [PATCH 3/4] Fix: Added observer for dynamic websites --- js/content-script.js | 36 +++++++++++++++++++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) diff --git a/js/content-script.js b/js/content-script.js index 8e774f0..f2fc28d 100644 --- a/js/content-script.js +++ b/js/content-script.js @@ -14,6 +14,33 @@ chrome.runtime.onMessage.addListener(function (message, sender, sendResponse) { const showTooltipEvent = jQuery.Event('showTooltip'); const timerIsZeroEvent = jQuery.Event('timerIsZero'); +// Observe if relevant input field is added +function registerElementChangeObserver(selector, callback) { + const observer = new MutationObserver((mutations) => { + mutations.forEach((mutation) => { + mutation.addedNodes.forEach((node) => { + // Nur Element-Knoten prüfen (keine Text-Knoten) + if (node.nodeType === 1) { + + // 1. Direktes Match prüfen + if (node.matches(selector)) { + callback(); + } + + // 2. Innerhalb von Containern suchen + const nestedMatches = node.querySelectorAll(selector); + nestedMatches.forEach(match => callback()); + } + }); + }); + }); + + // Observe if relevant input field is added + observer.observe(document.body, { + childList: true, + subtree: true + }); +}; // processing starts here and is continued when the background script sends the extracted domain passSec.url = document.location.href; @@ -26,8 +53,15 @@ $(document).ready(function () { passSec.websiteProtocol = document.location.protocol; chrome.storage.local.get(null, function (items) { + // Process ones on pagelaod processInputs(items); + // Register observer + registerElementChangeObserver( + 'input:not([type=submit],[type=reset],[type=button],[type=image],[type=radio],[type=checkbox]):read-write,textarea:read-write', + () => processInputs(items) + ); + // normally the focus event handler would be enough here, but we need the mousedown down handler // and the 'inputElementClicked' flag to accomplish the following: When the user closes the tooltip // by clicking 'Ok, got it.', the tooltip should open up again when clicking on the still focused @@ -222,4 +256,4 @@ function applyTooltip(element, event) { }, event); } -} \ No newline at end of file +} From 2b5bd0e07a7a606c5bd5a049e4d90b1bc2886854 Mon Sep 17 00:00:00 2001 From: granlem Date: Wed, 11 Mar 2026 14:08:08 +0100 Subject: [PATCH 4/4] Bump extension version to 3.4.1 --- manifest.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/manifest.json b/manifest.json index ccca977..977d4bf 100644 --- a/manifest.json +++ b/manifest.json @@ -1,7 +1,7 @@ { "manifest_version": 3, "name": "PassSec+", - "version": "3.4", + "version": "3.4.1", "author": "SECUSO", "homepage_url": "https://www.secuso.org/passsec", "description": "__MSG_addOnDescription__", @@ -68,4 +68,4 @@ }, "default_title": "__MSG_browserActionRedirectActive__" } -} \ No newline at end of file +}