Write-only input fields


#1

A user’s credentials are valuable, and are often the key target of phishing and content injection attacks. If a content injection attack can trick a user’s credential manager into autofilling her credentials, then the user’s credentials will be available to the attacker directly via DOM APIs or indirectly via form submission to a malicious endpoint. The latter risk can be mitigated via the Content Security Policy form-action directive, but the former is a real problem. If passwords are a simple value accessor away, users are at risk.

We could mitigate this latter risk by allowing sites to opt-in to denying DOM access to an input element’s content. If JavaScript can’t grab the value, then script injection attacks have a much more difficult time of exfiltrating interesting data. This might be as simple as adding a writeonly attribute to input elements:

<input writeonly type="password">

This would throw an InvalidStateError on value* accessors, bar the element from constraint validation, block keydown, keyup, keypress events, and probably other things I haven’t considered yet.

This state could also be controlled via a Content Security Policy directive which would set writeonly state for some arbitrary set of input elements, perhaps based on autocomplete attribute values. Perhaps:

Content-Security-Policy: form-writeonly cc-number cc-csc ... current-password new-password

I’ve strawmanned this out in a bit of detail at https://mikewest.github.io/credentialmanagement/writeonly/, and there was a short-lived public-webapps thread at http://lists.w3.org/Archives/Public/public-webapps/2014JulSep/0165.html


Disable “Show password” if autofilled
Can we get a "Security" category?
#2

If someone can do content-injection, can’t they insert a full <form> (or insert a script that does the necessary modifications to an existing <form>) with the target of their choosing? There’s no need to read the DOM value out of an input if you can just submit the form yourself.

Similarly, script injection can just remove the writeonly attribute and then read content freely. CSP-based application might mitigate this, but still wouldn’t avoid the “just submit the form” attack.


#3

Yes. Form injection is why I think something like CSP would be a necessary component.

CSP would mitigate “just submit the form” by controlling the endpoints to which forms may be submitted via the form-action directive.

What probably also isn’t clear from the proposal is that a theoretical credential manager spec could provide sites/users with some way of specifying “writeonly-only” for saved credentials (similar to ‘httponly’ for cookies).


#4

Hey @mikewest,

This is something I have been brainstorming recently in relationship to using COWL (which yeah that needs to solidify first).

I think the CSP restriction feels a little fragile in that x provider might want to give me the same input fields too which collides with something I want to do. However as mentioned the other side of this is that the CSP is there to protect these fields.

My current thinking was using a label like this:

<input writeonly type="password" cowl-label="https://x-pass-manager.com" />

Which in this case wouldn’t be readable by anything other than scripts with access to that label.

So WebAppSec might be able to pick this back up I guess however it would be interesting to thrash this out here too.