The Invisible Passenger in Your Browser

You're on your bank's login page. You type your password. The field turns it into dots almost instantly, that familiar visual reassurance. What you don't see is the grammar checker you installed three weeks ago, still running, reading the raw characters off the input event before the masking layer even blinks.

Not a hack. Not a glitch. Working as intended.

Somewhere around your third or fourth extension, you stopped reading the permissions screen. Most people do. You click "Add to Chrome," the puzzle piece appears in the toolbar, and you move on. What you may not realize is that some of those extensions have been reading every form field you touch ever since. Keystrokes, passwords before they're masked, credit card numbers mid-entry.

So what actually decides whether an extension can do that?

The Permission System Is a Negotiation, Not a Wall

Browser extensions run inside a permissions model, a kind of contract declared in a file called the manifest. When a developer builds an extension, they list the capabilities they're asking for. You install it, the browser presents those requests, you accept, and the contract is live. Simple. Mostly invisible.

The most powerful single permission is deceptively named. `activeTab` sounds modest, almost polite. It means the extension can access the full content of whichever tab you're currently looking at, including the DOM (the live structure of the page) and anything typed into it.

Then there's `tabs`, which gives access to your open tab list and URLs. Then host permissions, which look like `<all_urls>` or `https://.google.com/`. A host permission covering all URLs is the master key. It means the extension can inject a content script, a small piece of JavaScript, into every page you load. That script can listen for input events. It can read what you type the moment you type it, before the data ever leaves your browser.

This is the mechanism. Not a bug. Intended, documented behavior.

What a Content Script Actually Does

Back to that grammar checker. Reasonable tool, useful function. It needs to read your text to do its job, so it declares `<all_urls>` as a host permission and you click accept.

Now you navigate to your bank. The grammar checker's content script is already running on that page, because the host permission said every URL, no exceptions. The script attaches an event listener to every `<input>` field. You type your username. You type your password. The field masks the characters visually, showing dots. But the content script reads the `input` event before the masking layer does anything. It sees the raw characters.

Most grammar checkers aren't doing anything malicious with that. The data usually gets filtered, or the developer has specifically excluded password fields. But the architecture allows it, and there is no technical enforcement stopping a badly written or deliberately malicious extension from logging that data and shipping it to a remote server.

That's not paranoia. That's just how content scripts work.

The Manifest Version Gap

Chrome extensions currently exist in two generations: Manifest V2 and Manifest V3. The move to V3 was partly a security push, and it does tighten some things. Extensions can no longer execute arbitrary remote code at runtime, which closes one notable attack vector.

But host permissions still exist in V3. An extension can still request `<all_urls>`. The ability to read form inputs via content scripts is intact. The structural risk didn't disappear; it got its edges sanded off, which is not the same thing as being fixed.

Firefox runs its own extension model with similar concepts. Safari uses a stricter sandbox and requires extensions to go through App Store review, which adds a human checkpoint. No browser has fully solved the problem, because the problem is partly definitional: an extension that reads what you type is sometimes doing exactly what you paid for.

What People Get Wrong About This

The common assumption is that the lock icon in your address bar, the one signaling HTTPS, protects you from extensions. It does not. HTTPS encrypts data in transit, between your browser and the server. A content script runs inside the browser, before that encryption step. The lock is completely irrelevant to what an extension can see. Treating those two things as the same protection is like assuming a sealed envelope protects you from someone standing in the room while you write it.

The second misconception, and honestly the more dangerous one, is that extensions from reputable sources are categorically safe. Extensions get acquired. A popular extension with 400,000 users is an attractive acquisition target for anyone who wants a ready-made data pipeline. The original developer sells, the new owner pushes an update, permissions expand. Users who installed years ago auto-update and never see a new permissions prompt, because Chrome and Firefox only re-prompt for permission upgrades in some cases, not all.

This isn't hypothetical. Several extensions with large user bases have been acquired and turned into adware or worse after their original developers moved on. The name you trusted is still in the toolbar. The code underneath is different.

How to Check What You've Already Installed

In Chrome, go to `chrome://extensions`, click "Details" on any extension, and look at the permissions list. If you see "Read and change all your data on all websites," that extension has a content script with broad host permissions. It can read what you type on every site.

Found one? Ask yourself: does this extension actually need to see every page I visit to do its job? A password manager, yes, obviously. A tab color-coder, no. When the permissions exceed the function, that gap deserves a real answer, either a setting change or an uninstall.

Firefox surfaces this more clearly in its `about:addons` page, and it lets you set some permissions to "Ask each time" rather than granting them permanently, which is a genuinely useful option that almost nobody uses.

The practical check takes four minutes. The permissions screen you skipped on a Tuesday afternoon two years ago is still in effect, still running, still watching your keyboard. Checking it now doesn't undo that, but at least you'll know what you're actually running inside your browser, which seems like the minimum bar for software you've trusted with your passwords.