9

Most sites having a sign in form have the following html element:

<input type="password" />

If I press F12 to open the debugger on chrome and type:

document.getElementByName("password")[0].value

this will retrieve the password. A hacker could write a XSS in which the password is read and sent to his server then log in my CMS. In Bank of America's website, the password's input value is shown as "secret", they have a solution to protect it. The real password is unaccessible, thus protected.

What are some solutions to this?

13
  • 15
    "In Bank of America's website, the password's input value is shown as "secret", they have a solution to protect it." - I doubt that this is a 100% protection. They might have a way to make it harder, but not to fully protect it. XSS can also be used to inject a key logger, hijack the final form submit or track changes to the DOM in order to retrieve the password. The proper way is to protect against XSS in the first place, for example by using strict Content Security Policy. Apr 1, 2021 at 5:24
  • 11
    "A hacker could write a XSS" - You should use the normal measures to prevent XSS. First of all, filter user input properly.
    – mentallurg
    Apr 1, 2021 at 5:28
  • 3
    In Bank of America's website, the password's input value is shown as "secret" - I can't reproduce this. For me, the value of the password box is accessible via the browser console.
    – nobody
    Apr 1, 2021 at 9:16
  • 27
    Don't be vulnerable to XSS, easy.
    – user163495
    Apr 1, 2021 at 10:11
  • 5
    OP: you write, A hacker could write a XSS in which the password is read and sent to his server. The problem comes down to how the attacker would insert this malicious piece of client-side code into BOA's web site. As some of the other answerers and commenters have suggested, this is exactly why sites like BOA go to such great lengths to prevent this.
    – mti2935
    Apr 1, 2021 at 13:17

5 Answers 5

25

The only reasonable solution, as commented multiple times, is to protect against XSS on the very beginning. You don't want to focus on the password box.

A successful XSS can do any possible harm to the web page, not limited to sniffing the input box, but also to redirecting the login form to possibly anywhere else, social engineer an official endorsement (BofA detected a security flaw in your browser, hurry and download our extension is a very succesful malvertising).

The browser is software under the user's control, so Developer Tools exist to help the (advanced) user take full ownership of the HTML document which is run on their end.

I believe your approach is wrong for this reason. As soon as your login page cannot be contaminated by XSS, and as soon the user is not installing a keylogger/malware extension into their browser, you have no reason to protect the password box.

Protecting from XSS is a totally different topic.

19

There are various things you could attempt, but none of them will meaningfully do anything. For example, you can intercept each typed character, store it in a JS variable, and then replace it in the input with something menaingless. Reading the value of the input won't get the attacker anything, but they can just read the JS variable instead. You can hide the variable by putting it in a private closure with no read functions - only ones to update the password as it's typed, and one to send it to the server - but that's not going to hide it from somebody who does the same kind of thing, monitoring keystrokes or changes to the input in real time. You could try messing with the property accessors in the DOM. Specifically, overriding value on the input element so that it doesn't return the real value is possible, and probably what BoA did. It doesn't actually add any real security because there's so many other ways to either monitor keystrokes, etc. or to extract the full password anyhow. Some ways: get the outerHTML of the input or any containing element, or innerHTML of any containing element, or if it uses an HTML form edit the action (destination) to point to your own site, or use DOM manipulation to remove or overlay the not-JS-readable password input with one that the JS can read (before the user starts to type), or...


One option might be to use a sandboxed iframe for the actual login form. Something like <iframe sandbox="allow-forms allow-top-navigation-by-user-activation"... > which prevents script execution and prevents the frame contents from being read by the parent. Put the login form, and all dynamically-generated content (that might be subject to XSS), on the page that loads inside the iframe. Add a script that immediately navigates the user away if scripts are allowed at all (they won't be, inside the sandbox), and use X-Frame-Options and/or CSP's frame-ancestors to prevent third-party pages from loading the login page in an iframe. Inside the iframe, you can have a standard HTML form, and give it a target="_top" attribute to make it load the login result in the top-level context. Any injected script (which is what XSS generally is) won't run because of the sandbox. (Of course, no other script will either, for the same reason, so your login form will have to cope with that). Don't put any dynamic content in the parent page (where scripts work), because even though the password input isn't in a scripts-work zone, XSS in the parent page could replace or edit the entire iframe with one more amenable to stealing your data.


Or you could just do the reasonable thing and stop chasing this fringe benefit of protecting a specific input field from XSS (most XSS happens after authentication, after all). Keep your login page simple. Don't use external scripts (or any scripts, unless they directly relate to the basic functionality of logging in). Don't use any user-supplied input if you can help it; if you can't help it for some reason, make sure it's output encoded and maybe input validated for good measure. Don't do any DOM modification that could enable DOM-based XSS. Add highly restrictive CSP (which should be EASY for such a clean page) for defense-in-depth. Voila: your password input is protected from XSS.

1
  • Suggest you mention that a lot of these things (e.g., intercepting keystrokes) will probably completely break password managers, break accessibility, etc. Otherwise it sounds like its relatively harmless (though ineffective).
    – derobert
    Apr 6, 2021 at 18:27
13

This is more of a clarifying question rather than an answer, but won't fit in a comment.

You said:

In Bank of America's website, the password's input value is shown as "secret", they have a solution to protect it.

If that's true, I would also love to learn what they are doing, but I don't see it.

Bank of America document.getElementById("passcode1").value

You can also easily un-mask the password field:

Bank of America unmasking the password field

This is normal; every website I have ever tested behaves the same way; there's not much you can do to protect the password field from either the user sitting at the browser, or javascript on the page (which legitimately needs to read the value of that textbox in order to process it and send it to the server).

If there is some security functionality on the BoA site with regards to their password field, could you be more specific? (and I'll update my answer)

2
  • 18
    Perhaps the OP's password was "secret" :-)
    – abligh
    Apr 1, 2021 at 16:08
  • 9
    @abligh Users are advised to "keep their password 'secret'"
    – Barmar
    Apr 2, 2021 at 14:49
4

An XSS would trigger when a malicious actor manages to inject javascript inside a page. This happens really rarely in login pages, mainly because the content served is static. In case there is an XSS in a login page, it is possible indeed for an attacker to steal their credentials by doing a request on their server, which is a common approach. A CSP would block this request but it is not sufficient in multiple cases, since big corpos have quite complex networks.

For your debugger issue, on the BoA website, is you run in your console document.getElementById('passcode1').value, you will still get the value. I don't believe there is a way to prevent it, because your credentials should be submitted somehow.

1

Being able to read the contents of the password field is expected behavior. Browser security does not prevent the browser itself from being able to view the HTML once the site is opened. Similarly, the user is extended this permission since developers or power users often need or want to tweak features of the site.

Instead, the BoA's (and whatever other site's) security is provided by ensuring that visits to their webpage only download their code to you, the viewer. This is usually done by input sanitization and making the login page ONLY accept logins (so that someone can't craft a URL that makes the site embed an extra script).

XSS happens when someone writes a fake browser plugin or finds a vulnerability in the hosting server (or connection, or URL encoding...) that lets them embed their own scripts into the BoA page. Once this happens, the attacker's JavaScript can read the content the same way that the legitimate page does (which is indeed bad).

However, you're normally safe from this, since (for example) your command will only work while you are viewing the BoA page. If you switch over to your tab with (again, for example) StackExchange open, the command will no longer get your password. Similarly, scripts from StackExchange can't read your password either (sites are also configured so that StackExchange's page can't send or receive data from BoA's server either).

That's why XSS exists: normally, only you and BoA can access that password field. Workarounds have to be taken to let other sites or people get access to that data, since you asked for BoA's site, and BoA's site only loads BoA's scripts (not malicious%20actor.net's scripts). Short of someone finding a zero-day vulnerability in the site, the only way that you can end up loading malicious scripts are by installing untrusted extensions/plugins, failing to use HTTPS when logging in (your browser will usually warn you--read your particular browser's docs on how), or by clicking suspicious links sent to you rather than you physically visiting BoA.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .