©2014 Google
This specification describes how a website can ask a user agent to deny read access to form elements, which can mitigate the risk of credential leakage via cross-site scripting attacks.
This section is not normative.
A user’s credentials are valuable, and are often the key target of phishing and content injection attacks.
Users can defend themselves from the former threat by using a credential manager which enables the generation of strong, unique passwords for all the sites they visit, and which only provides those credentials to the website they’re tied to. If a user relies on a credential manager to keep track of her passwords, and the credential manager refuses to fill them into forms on unexpected origins, phishing becomes significantly more difficult.
Content injection, on the other hand, can turn the credential manager against
  the user, as demonstrated in "Automated Password Extraction Attack on Modern
  Password Managers" [LUPIN]. If an attacker can inject a form into a website
  and the credential manager can be tricked into filling it, 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
  [CSP2], but the former is a real problem. If passwords are a simple "value"
  accessor away, users are at risk.
It is tempting to simply block read access to password fields, but many websites do interesting things with password fields. They increasingly read credential values in order to sign a user in via XMLHttpRequest, for instance, rather than submitting a form. A blanket restriction is therefore unlikely to be web-compatible.
Instead, this document proposes an opt-in mechanism by which a website can choose to deny itself read access to the values of particular form fields. User agents could (and should!) allow credential managers to help users sign-in by writing values into form fields, but those values would remain opaque to the website’s JavaScript.
<form action="/signin-endpoint" method="POST">
  <input type="text"
         autofill="username"
         name="username">
  <input type="password"
         writeonly
         autofill="current-password"
         name="password">
  <input type="submit">
</form>
  Content-Security-Policy: form-writeonly current-password new-password;
Note: A real page’s policy should also include form-action and connect-src directives to mitigate the risk of exfiltration.
Developers may opt-into preventing DOM access to form fields by setting a
  writeonly attribute on specific
  form or form-associated elements, or by using the
  form-writeonly Content Security Policy directive to
  prevent DOM access to any and all form-associated elements based on
  their autocomplete attributes. Both
  mechanisms are described below:
writeonly attributewriteonly is a boolean attribute
  that controls whether or not an element’s value may be read directly via the
  value IDL attribute, or inferred via the
  constraint
  validation API [HTML5].
partial interface HTMLInputElement {
    attribute boolean writeonly;
};
  writeonly content attribute.Copy/paste this IDL for button, keygen, object, select, and textarea.
partial interface HTMLFormElement {
    attribute boolean writeonly;
};
  writeonly content attribute.If the writeonly attribute is set for an input element
  input, then set input’s write-only value flag
  to true.
If the writeonly attribute is set for a form
  element form,then set the write-only value flag to
  true for all submittable elements whose form owner
  is form.
Note: Removing the writeonly attribute will
  not clear an element’s write-only value flag. Once that flag is set for
  an element, it cannot be cleared.
form-writeonly Content Security Policy directive
  The form-writeonly directive specifies a policy
  which affects how the user agent interprets input elements in
  a protected resource. The syntax for the name and value of the directive are
  described by the following ABNF grammar [ABNF]:
directive-name = "form-writeonly" directive-value = "" / *WSP [ autocomplete-token *[ 1*WSP autocomplete-token ] *WSP ] autocomplete-token = <any valid autofill detail tokens>
When enforcing the credentials directive, the user agent MUST set the
  protected resource’s forced write-only types to '*'
  if the directive’s value is empty, or to the list of autofill detail
  tokens specified by the directive’s value.
<input> element behaviorExpand this to include all submittable elements.
If an input element input’s write-only value
  flag is true, or if input’s
  Document's forced write-only types is '*',
  or if input’s autocomplete
  attribute contains one or more values which are also contained in
  input’s Document's forced write-only types, then the
  following restrictions apply:
autocomplete IDL attribute
      [HTML5], input’s write-only value flag MUST also be
      set to true.
Note: This prevents attackers from bypassing the CSP directive by changing
      the element’s autocomplete value from
      current-password to something unprotected
      (like section-fake).
InvalidStateError exception. [HTML5]
Note: Setting these attributes is unaffected.
selectionStart and selectionEnd IDL
      attributes will throw an InvalidStateError
      exception. [HTML5]
Note: Setting these attributes is unaffected.
keydown, keyup, or
      keypress events on input. [DOM-LEVEL-3-EVENTS]
    FormData
      objects constructed from the form which contains input are
      opaque, as described in §2.4 
    Opaque FormData objects
  
    Is this more or less exhaustive? I’m sure I’m missing some clever ways of reading the value.
FormData objects
  FormData objects have a opaque flag, unset by default,
  and set only if the object is constructed from a form
  containing one or more input elements whose write-only value
  flag. Opaque FormData objects return null and
  the empty sequence when their
  get()
  and
  getAll()
  methods are executed, respectively. Further, data from opaque
  FormData objects can only be
  extracted
  in the context of executing 
  XMLHttpRequest’s send() method.
Opaque FormData objects have the following properties:
FormData object’s
      get()
      method, it MUST return null.
    FormData object’s
      getAll()
      method, it MUST return the empty sequence.
    Content-Type
      from an opaque FormData object formdata, first
      the following steps:
      send() method,
          Fetch’s Request constructor,
          or
          Fetch’s Response constructor
          then skip the next step and proceed executing the algorithm.
        Content-Type
          algorithm on a new (empty) FormData object.
        Monkey-patching! Hooray! Though, of course, that’s pretty much this whole strawman...
FormData constructorInsert the following steps before step 3 of
  the FormData
  constructor’s algorithm:
true, then set fd’s opaque flag.
            FormData’s get()Redefine FormData’s
  get()
  method as follows:
null.null if no such
      entry
      exists.
    FormData’s getAll()Redefine FormData’s
  getAll()
  method as follows:
Request objectsAdd a new opaque request flag to
  Fetch’s Request objects.
  This flag is unset unless otherwise specified.
Request’s constructorAdd the following step after step 3 of step 17 of
  Fetch’s Request constructor:
body member is a FormData
      object whose opaque flag is set, set r’s opaque
      flag.
    Body’s consume bodyInsert the following step after step 2 of step 3 of
  Body’s as generic
  algorithm:
Redefine the FormData case of Fetch’s
  extract a byte stream and Content-Type
  algorithm as follows:
send() method
      or
      Fetch’s Request constructor
then:
text/plain;charset=UTF-8.
Note: In this case (e.g. object is opaque
      and the algorithm isn’t being executed as a result of
      XHR.send()), stream will remain an empty byte
      stream.
Figure out the right way to monkey-patch Service Worker’s Handle a Fetch algorithm to do the right thing with opaque requests.
This section is non-normative.
Some user agents are implemented in such a way as to render websites via low-privilege processes that don’t have direct access to the network. Network requests are mediated by a more privileged parent process, which can protect against a number of threats which arise if a clever attacker can exploit bugs in the user agent to corrupt the website’s process.
Even if we prevent DOM-level access to input fields, the form field is somehow represented in memory that’s accessible to that child process. It is quite conceivable that an attacker could exploit browser bugs which corrupt the child process in such a way as to expose a user’s credentials.
Marking fields as write-only might mitigate this risk in the case of autofilled credentials. Since the webpage does not need access to a user’s actual password, the parent process can generate a nonce when autofilling credentials, and ask the child process to fill the password field with that value instead of the actual password. Then, when the child process asks the parent process to POST a form, the parent process can replace occurrences of the nonce in the POST’s body with the actual password for a given credential.
This approach means that the actual credentials are never provided to the high-risk child process, which means that an attacker would have to break out of the child’s sandbox in order to steal credentials.
A more rigorous examination of this approach is undertaken in "Protecting Users Against XSS-based Password Manager Abuse" [STOCK]. Their use of a browser extension is instructive: there’s no reason that this scheme couldn’t be implemented by a third-party credential manager, as long as it has access to the data POSTed from one page to another.
This section is non-normative.
In order to mitigate the risk of content injection attacks which steal user credentials, we recommend that authors:
form-action,
      connect-src
      and form-writeonly directives. The first will protect
      against autofilled form submissions which exfiltrate data to an attacker’s
      origin, the second against XHR-based submissions, and the last against
      DOM-level content injection attacks.
    This proposal is heavily inspired by Jacob S Hoffman-Andrews' comments on public-webapps@, as well as Brian Smith’s response. Anne van Kesteren helped immensely with the Fetch integration.
Conformance requirements are expressed with a combination of descriptive assertions and RFC 2119 terminology. The key words “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “MAY”, and “OPTIONAL” in the normative parts of this document are to be interpreted as described in RFC 2119. However, for readability, these words do not appear in all uppercase letters in this specification.
All of the text of this specification is normative except sections explicitly marked as non-normative, examples, and notes. [RFC2119]
        Examples in this specification are introduced with the words “for example”
        or are set apart from the normative text with class="example", like this:
    
        Informative notes begin with the word “Note”
        and are set apart from the normative text with class="note", like this:
    
Note, this is an informative note.
partial interface HTMLInputElement {
    attribute boolean writeonly;
};
partial interface HTMLFormElement {
    attribute boolean writeonly;
};