MultiPassword, a password manager trusted by over 1 million users worldwide, leaked usernames, passwords, URLs and Time-based One Time Passcodes (TOTP) with a low skill attack, in specific but very common circumstances. There was no evidence this was being exploited in the wild.
This was the second major discovery I made with the AmIBeingPwned scanning pipeline.
CVSS: 4.0/AV:N/AC:L/AT:N/PR:N/UI:P/VC:H/VI:N/VA:N/SC:H/SI:N/SA:N 8.3
From October 2024 to March 2026, this extension was vulnerable (if Crx4chrome is to be believed). Versions 0.98.11 through 0.98.70.
Any site with the same Country Code Effective Top Level Domain (CC eTLD) could exfiltrate any other passwords from other sites with the same CC eTLD. For example evil.co.uk could access usernames, passwords, TOTP codes and URLs from hsbc.co.uk, same with .co.jp, .co.au etc…
With all of this said, MultiPassword doesn’t actually seem like a bad password manager, all of the fundamentals are there with actual E2EE, but there were a series of mistakes made in the implementation that just made this exploit possible.
The Exploit
This exploit came down to a few vulnerabilities:
- The “popover dropdown” on the extension allowed the user to use arrow keys and the enter key to select the items from the dropdown. This meant the page “main world script” you were visiting could control the popover for the suggested passwords on the page, not just the content script.
- The “suggestionItemsSelector” in MultiPassword matched the items using this selector: location.host.split(".").slice(-2).join(".") - Which meant hsbc.co.uk got mapped to co.uk and evil.co.uk got mapped to co.uk too, so the password manager “thought” that these shared CC eTLDs were the same hosts, a textbook “CWE-706: Use of Incorrectly-Resolved Name or Reference”.
- Decrypted metadata like credential URLs, “names” and “hasTOTP” flags were also leaked to the page, letting a bad actor know where to use the passwords, and which credentials had TOTP codes available, alongside encrypted passwords.
This exfil flow requires no user interaction and can get all credentials for sites with shared CC eTLDs, including usernames, passwords, TOTP codes and URLs so the attacker knows where to use them!
The leaked TOTP (Time-based One Time Passcodes) are just the code at the given time, not the seed.
This all highlights the importance of knowing which messaging flows you can trust with chrome extensions, it’s not an easy thing.
Background: Chrome Extension Messaging

As the simplified diagram points out, internal messaging in chrome extensions is not the easiest thing to do, but do you know which messaging channels can be trusted and which ones can’t?
As a general rule, anything from a webpage should be treated as untrusted, unless you restrict the origins. You shouldn’t send any data untrusted pages, and you shouldn’t allow web pages to message the extension.
But what if you’re a password manager and you need to be able to communicate with every page? This is where Content Scripts (CS) and extension page iframes come into play, at least with MultiPassword.
The way MultiPassword was meant to work:
- It looked out for interactions with username/password input boxes via the isolated content script
- It added in an iframe in below the box with a dropdown, listing the available logins
- Users could click the logins or use their arrow keys and enter keys to select which credential to use
Now, the first problem here is that the credentials listed weren’t only the credentials for the site, they were for all the sites that the user had, with the shared CC eTLD (.co.uk, .co.au etc…) which was just a bug, but this wasn’t very problematic on its own, but it could lead to the user selecting the wrong password.
Demo of amazon.co.uk creds showing up on ebay.co.uk
Now, we’ve got other credentials listed, where do we go from here?
The content script uses the iframe.contentWindow.postMessage messaging flow to post a message from the isolated content script, over to the iframe. This is done to forward keyboard input like “down” or “enter” for selecting the credentials to use.
The problem is, this “postMessage” isn’t using the browser messaging API, this is just posting a message to the iframe, which can be done by any script in the untrusted main world.
frame.contentWindow.postMessage({ message: 'controls.arrowKey', key: 'ArrowDown' }, '*');
frame.contentWindow.postMessage({ message: 'controls.acceptSelection' }, '*');
The untrusted page can send these commands to the iframe to get it to fill in these credentials, and it can iterate through each one of these credentials to get them all.
So the extension was sending the credential metadata (and encrypted passwords + TOTP seed) from the iframe, to the main page, which the content script picked up, then decrypted the passwords and filled in the credentials.
The problem here is that the main untrusted page could see this message too as it wasn’t using the chrome extension messaging API, it was using “parent.postMessage”.
The content script then picked up this message and decrypted the provided credentials and filled them in on the DOM. This also meant that if someone did obtain encrypted passwords from elsewhere, an attacker could post a message to get the decrypted output.
The main page could then read the DOM and see the decrypted usernames and passwords from there, and combining this with monitoring the posted messages, we also have URLs and other metadata which would make it easy to use these passwords.
So now we have a way to iterate through the credentials and exfiltrate the passwords.
TOTP codes were exfiltrated in a similar way, so I’m not going to go in depth on that here.
Aside from the CC eTLD bug, if proper extension messaging was used, this would have been avoided. This does also highlight the point of how confusing but important it is to do extension messaging securely. Anything that passes through the main world from an unknown origin cannot be trusted.
Check out the exploit script here on GitHub.
The Timeline
- 7th of Feb: I found and reported the exploit with a demo video to the listed email on the multipassword site.
- Thu 12 Feb: I emailed the CWS team and another email I found for MultiPassword
- 13th of Feb: Got a response from the Multipassword/pass-service.kz team saying they were looking into it
- 16th of Feb: The extension was taken down from the CWS, preventing new installs but not fixing the actual vulnerability, Multipassword said the CWS team were responsible for this, saying this slowed down the roll out of the patch
- 4th of March: The fix was released - I was told the delay here was due to the CWS team taking longer to approve it, although I’ve not confirmed with them.
Conclusion
MultiPassword actually seems like a relatively well thought out platform, the implementation E2EE doesn’t seem to leak the master keys to the server, from what I’ve seen, putting them ahead of some of their competition and the extension isnow fixed.
They have offered a $250 bounty for this, although there’s no public bug bounty yet sadly.
At the end of the day, you can have all the encryption in the world, but if you’re not properly validating the origin of where messages are coming from and making sure you don’t let messages leak to the wrong places, it completely defeats the point.
The irony here is that their E2EE is good enough that a compromised backend probably couldn't have leaked these credentials.
And finally, if you’re worried about what your extensions are doing, go check out amibeingpwned.com
Full exploit flow diagram

It's pretty difficult to lay this out, this isn't super clear so I'm just leaving this at the end.

