personal_asset

That "Remember Password" Box You Ticked Is Probably Sitting There Unencrypted

"Remember password" is often stored in plain text in the browser, and an auto-refresh mechanism can deadlock itself waiting for a request that never returns.

你随手点的"记住密码",很可能没加密,就摆在那儿

While doing a security review for a project recently, I came across the little "remember password" checkbox on the login page and thought nothing of it. The feature is everywhere — nearly every site has it under the login form, and ticking it saves you retyping your credentials next time. Who would expect trouble from that.

Then I followed the code down and realized I had underestimated it.

To implement "remember password," the browser needs somewhere to store the account details and read them back to autofill next time. That storage, for many sites, is localStorage — think of it as a small drawer the browser assigns to each site, which the site's code can open, read from, and write to at any time, and whose contents survive closing and reopening the browser.

This project's approach: stuff the username and password into that drawer as-is. No encryption, plain text. Which means any code that can run on this page can open the drawer and read the password out verbatim.

"Code that can run on the page" sounds like it requires breaking into a server, but the bar is much lower. Three common cases: the site has an XSS hole (an attacker injects an executable script into the page — not rare on small and mid-sized sites); a browser extension you installed reads the content of every page (plenty of free extensions do exactly this); or another script has been planted on your machine. None of these need to touch your credentials directly — one line of JavaScript running in your browser opens the drawer and takes the plaintext password.

This is completely different from "stay logged in." The proper approach issues a short-lived token; losing a token costs you one re-login, a few seconds of annoyance. A password is different — it is something you reuse in many places, and once it is taken, the holder can log into far more than this one site. The cost is long-term and chained. What separates high risk from low here is not whether something is stored, but how far the damage spreads if that something leaks.

I removed that "remember password" outright, keeping at most the username. For passwords, the answer to this question is: do not store them.

The same review turned up a subtler problem, unrelated to passwords and related to the word "automatic."

Many sites auto-renew login state: when a token is about to expire, the system quietly exchanges it for a new one using a refresh token, so you are never bounced back to the login screen. This project implemented that too, quite thoroughly — every request passes through a checkpoint (an interceptor, professionally speaking) that checks whether the token expired and triggers a refresh if it did.

The problem is the checkpoint itself. When the refresh token has also expired, the system fires a refresh request — and that request also passes through the same checkpoint. The checkpoint sees a request without valid login state, and tries to trigger another refresh. It is waiting on a refresh it issued itself that will never return. Every request piles up behind the checkpoint, no errors, just spinning, and the user sees a page stuck loading forever.

The two problems look unrelated — one is plaintext password storage, one is a logic deadlock — but the root cause is the same: when designing a mechanism that handles something automatically for you, only the normal path was thought through, not what happens the moment the mechanism itself fails. The "smarter" the convenience feature, the easier this step is to miss, because the designer's attention is entirely on reducing user effort, and few people ask what happens if the thing saving the user effort breaks first.

Both are easy to fix: for passwords, the answer is do not store them; for the deadlock, pull the refresh request out so it cannot trigger another refresh. What is hard was never the fix. It is whether anyone asks, during design, who carries the cost when this convenience fails.

Next time you casually tick "remember password" on some site, open the browser developer tools (F12), look under storage at localStorage, and see whether an unencrypted password is really lying there. Most large, reputable companies do not do this. Plenty of smaller sites might.

Sources