diff --git a/README.md b/README.md
index e028bf4..3932a8b 100644
--- a/README.md
+++ b/README.md
@@ -1,177 +1,16 @@
-# Explainer for the TODO API
+# Explainer for the policy-controlled features `autofill` and `manual-text`
-**Instructions for the explainer author: Search for "todo" in this repository and update all the
-instances as appropriate. For the instances in `index.bs`, update the repository name, but you can
-leave the rest until you start the specification. Then delete the TODOs and this block of text.**
-
-This proposal is an early design sketch by [TODO: team] to describe the problem below and solicit
+This proposal is an early design sketch by the Chrome Autofill team to describe the problem below and solicit
feedback on the proposed solution. It has not been approved to ship in Chrome.
-TODO: Fill in the whole explainer template below using https://tag.w3.org/explainers/ as a
-reference. Look for [brackets].
-
-## Proponents
-
-- [Proponent team 1]
-- [Proponent team 2]
-- [etc.]
-
## Participate
-- https://github.com/explainers-by-googlers/[your-repository-name]/issues
-- [Discussion forum]
-
-## Table of Contents [if the explainer is longer than one printed page]
-
-
-
-
-
-- [Introduction](#introduction)
-- [Goals](#goals)
-- [Non-goals](#non-goals)
-- [User research](#user-research)
-- [Use cases](#use-cases)
- - [Use case 1](#use-case-1)
- - [Use case 2](#use-case-2)
-- [[Potential Solution]](#potential-solution)
- - [How this solution would solve the use cases](#how-this-solution-would-solve-the-use-cases)
- - [Use case 1](#use-case-1-1)
- - [Use case 2](#use-case-2-1)
-- [Detailed design discussion](#detailed-design-discussion)
- - [[Tricky design choice #1]](#tricky-design-choice-1)
- - [[Tricky design choice 2]](#tricky-design-choice-2)
-- [Considered alternatives](#considered-alternatives)
- - [[Alternative 1]](#alternative-1)
- - [[Alternative 2]](#alternative-2)
-- [Stakeholder Feedback / Opposition](#stakeholder-feedback--opposition)
-- [References & acknowledgements](#references--acknowledgements)
-
-
-
-## Introduction
-
-[The "executive summary" or "abstract".
-Explain in a few sentences what the goals of the project are,
-and a brief overview of how the solution works.
-This should be no more than 1-2 paragraphs.]
-
-## Goals
-
-[What is the **end-user need** which this project aims to address? Make this section short, and
-elaborate in the Use cases section.]
-
-## Non-goals
-
-[If there are "adjacent" goals which may appear to be in scope but aren't,
-enumerate them here. This section may be fleshed out as your design progresses and you encounter necessary technical and other trade-offs.]
-
-## User research
-
-[If any user research has been conducted to inform your design choices,
-discuss the process and findings. User research should be more common than it is.]
-
-## Use cases
-
-[Describe in detail what problems end-users are facing, which this project is trying to solve. A
-common mistake in this section is to take a web developer's or server operator's perspective, which
-makes reviewers worry that the proposal will violate [RFC 8890, The Internet is for End
-Users](https://www.rfc-editor.org/rfc/rfc8890).]
-
-### Use case 1
-
-### Use case 2
-
-
-
-## [Potential Solution]
-
-[For each related element of the proposed solution - be it an additional JS method, a new object, a new element, a new concept etc., create a section which briefly describes it.]
-
-```js
-// Provide example code - not IDL - demonstrating the design of the feature.
-
-// If this API can be used on its own to address a user need,
-// link it back to one of the scenarios in the goals section.
-
-// If you need to show how to get the feature set up
-// (initialized, or using permissions, etc.), include that too.
-```
-
-[Where necessary, provide links to longer explanations of the relevant pre-existing concepts and API.
-If there is no suitable external documentation, you might like to provide supplementary information as an appendix in this document, and provide an internal link where appropriate.]
-
-[If this is already specced, link to the relevant section of the spec.]
-
-[If spec work is in progress, link to the PR or draft of the spec.]
-
-[If you have more potential solutions in mind, add ## Potential Solution 2, 3, etc. sections.]
-
-### How this solution would solve the use cases
-
-[If there are a suite of interacting APIs, show how they work together to solve the use cases described.]
-
-#### Use case 1
-
-[Description of the end-user scenario]
-
-```js
-// Sample code demonstrating how to use these APIs to address that scenario.
-```
-
-#### Use case 2
-
-[etc.]
-
-## Detailed design discussion
-
-### [Tricky design choice #1]
-
-[Talk through the tradeoffs in coming to the specific design point you want to make.]
-
-```js
-// Illustrated with example code.
-```
-
-[This may be an open question,
-in which case you should link to any active discussion threads.]
-
-### [Tricky design choice 2]
-
-[etc.]
-
-## Considered alternatives
-
-[This should include as many alternatives as you can,
-from high level architectural decisions down to alternative naming choices.]
-
-### [Alternative 1]
-
-[Describe an alternative which was considered,
-and why you decided against it.]
-
-### [Alternative 2]
-
-[etc.]
-
-## Stakeholder Feedback / Opposition
-
-[Implementors and other stakeholders may already have publicly stated positions on this work. If you can, list them here with links to evidence as appropriate.]
-
-- [Implementor A] : Positive
-- [Stakeholder B] : No signals
-- [Implementor C] : Negative
-
-[If appropriate, explain the reasons given by other implementors for their concerns.]
-
-## References & acknowledgements
+- https://github.com/explainers-by-googlers/safe-text-input/issues
-[Your design will change and be informed by many people; acknowledge them in an ongoing way! It helps build community and, as we only get by through the contributions of many, is only fair.]
+## Motivation
-[Unless you have a specific reason not to, these should be in alphabetical order.]
+User input on the Web platform is origin-agnostic: any document, even a third party one, can receive input like clicks or keys – not even the embedding document can prevent that. When the user cannot recognize third-party content as such, e.g., because it lacks visual separation as it often does with borderless iframes, this bears the risk of inadvertently disclosing sensitive information to untrusted third parties.
-Many thanks for valuable feedback and advice from:
+The underlying problem is that the user's trust in the top-level document implicitly propagates to third-party embeddees. We propose to break this propagation and make the embedder responsible for delegating the ability to receive input to trusted embeddees. We introduce two new [policy-controlled features](https://www.w3.org/TR/permissions-policy/#features) for that purpose:
-- [Person 1]
-- [Person 2]
-- [etc.]
+* [manual-text.md](manual-text.md) introduces `manual-text` for keyboard input and similar manual ways of entering text.
+* [autofill.md](autofill.md) introduces `autofill` for user agent features that fill one or multiple form control elements on behalf of the user.
diff --git a/autofill.md b/autofill.md
new file mode 100644
index 0000000..b9ba81b
--- /dev/null
+++ b/autofill.md
@@ -0,0 +1,263 @@
+# Policy-controlled feature `autofill`
+
+This proposal is an early design sketch by the Chrome Autofill team to describe the problem below and solicit
+feedback on the proposed solution. It has not been approved to ship in Chrome.
+
+## Participate
+- https://github.com/explainers-by-googlers/safe-text-input/issues
+
+## Table of Contents
+
+
+
+
+
+- [Motivation](#motivation)
+- [Autofill](#autofill)
+- [Goals](#goals)
+- [Non-goals](#non-goals)
+- [Proposal](#proposal)
+- [Use-cases](#use-cases)
+ - [Example 1: limiting the scope](#example-1-limiting-the-scope)
+ - [Example 2: extending the scope](#example-2-extending-the-scope)
+ - [Example 3: multiple origins](#example-3-multiple-origins)
+- [Security and privacy](#security-and-privacy)
+ - [Eavesdropping due to overly permissive policies](#eavesdropping-due-to-overly-permissive-policies)
+ - [Trusted documents embedded in untrusted documents](#trusted-documents-embedded-in-untrusted-documents)
+ - [Clickjacking](#clickjacking)
+- [Relationship of `autofill` and `manual-text`](#relationship-of-autofill-and-manual-text)
+
+
+
+## Motivation
+
+User input on the Web platform is origin-agnostic: any document, even a third party one, can receive input like clicks or keys – not even the embedding document can prevent that. When the user cannot recognize third-party content as such, e.g., because it lacks visual separation as it often does with borderless iframes, this bears the risk of inadvertently disclosing sensitive information to untrusted third parties.
+
+The underlying problem is that the user's trust in the top-level document implicitly propagates to third-party embeddees. We propose to break this propagation and make the embedder responsible for delegating the ability to receive input to trusted embeddees. We introduce two new [policy-controlled features](https://www.w3.org/TR/permissions-policy/#features) for that purpose.
+
+Input can come from different sources: directly from the user via input devices like a mouse or keyboard, or from the user agent when it interacts with the website on behalf of the user. Our proposal focuses on two sources that we consider most susceptible to revealing sensitive information:
+
+* keyboard input (from physical or virtual devices) and
+* autofill features, under which we broadly subsume user agents' features that fill one or multiple form control elements with relatively little user interactions.
+
+This document addresses the second bullet point. An [affiliated document](manual-text.md) addresses the other bullet point.
+
+This proposal is intended as a step towards a web where text user input is disabled by default in cross-origin subframes.
+
+## Autofill
+
+Many user agents have features for automatically filling forms on behalf of the user. These features can be categorized along the following dimensions:
+
+* Type of data:
+ * structured data: e.g., addresses, credentials, or credit cards.
+ * unstructured data: e.g., values memorized from past forms.
+* Interaction model:
+ * no UI: e.g., autofill credentials on page load without user interaction.
+ * field-anchored UI: e.g., display suggestions next to the currently focused DOM element.
+ * unanchored UI: e.g., show a button outside of the web content area.
+* Scope:
+ * single field: e.g., autocomplete the currently focused field.
+ * fields of a form: autofill potentially multiple fields of the form associated with the currently focused field.
+ * fields of the page: autofill fields potentially outside of the current form, potentially in other frames.
+
+## Goals
+
+* Allow user agents to safely extend the scope of autofill across trusted origins.
+* Help user agents to warn users before autofilling values into untrusted origins.
+
+## Non-goals
+
+* Extend or limit the scope of autofill depending on the anchor's origin (in the [field-anchored interaction model](#def-field-anchored-interaction-model)).
+* Provide a way of turning autofill off.
+
+## Proposal
+
+We propose a policy-controlled feature `autofill` which recommends the user agent not to autofill into documents where the feature is disabled. The precise semantics is:
+
+If the policy-controlled feature `autofill` is [disabled](#def-disabled) in a document, the user agent SHOULD NOT [autofill](#def-autofill) a form control element in that document.
+
+The user agent autofills a set of form control elements when it modifies their [values](https://html.spec.whatwg.org/#concept-fe-value) on behalf of the user.
+
+A [policy-controlled feature](https://www.w3.org/TR/permissions-policy/#features) is disabled in a document iff the result of executing [Is feature enabled in document for origin?](https://w3c.github.io/webappsec-permissions-policy/#is-feature-enabled) on the feature, the document, and the document's [origin](https://dom.spec.whatwg.org/#concept-document-origin) is `"Disabled"`.
+
+The [default allowlist](https://www.w3.org/TR/permissions-policy/#default-allowlists) is `'self'`.
+
+## Use-cases
+
+### Example 1: limiting the scope
+
+Cross-origin iframes should often be allowed to present data to, but not to receive data from, the user. For example, consider a news website that embeds a cross-origin advertisement:
+
+```html
+
+
+
+
+
+```
+
+```html
+
+
+
+
+```
+
+It is clearly not desirable for the user to enter their username or password for the news website in the third-party ad frame.
+
+Indeed, `autofill` is disabled in `ad.html` since the document is cross-origin and the default allowlist is `'self'`. (The website can also make this explicit by adding an [allow attribute](https://w3c.github.io/webappsec-permissions-policy/#iframe-allow-attribute)
to the iframe
element: allow="autofill 'none'"
.)
+
+Following the [semantics](#def-autofill-feature) of `autofill`, the user agent should simply exclude the fields in `ad.html` from the scope of any autofill operation.
+
+For the fields in `ad.html`, browsers that employ the [field-anchored interaction model](#def-field-anchored-interaction-model) (as do Chrome, Firefox, Safari) may prefer to display autofill suggestions and include a warning to the user. As an example, such a warning could look as follows:
+
+![The user agent warns the user that the autofill may expose data to potentially untrustworthy parties.](images/warning-autofill.png)
+
+To prevent major breaking changes, we recommend that user agents ramp up the consequences of `autofill` incrementally. For example, the rollout could proceed in three stages:
+
+1. Autofill as usual but inform the web developer (e.g., in the JavaScript console) if a form control from a document where `autofill` is disabled is in the scope of the autofill.
+2. Warning the user if a form control from a document where `autofill` is disabled is in the scope of an autofill.
+3. Exclude form controls of documents where `autofill` is disabled from the scope of an autofill.
+
+### Example 2: extending the scope
+
+In some cases, text input is legitimate in cross-origin iframes. A common example are payment forms, which intentionally live in cross-origin iframes to isolate their contents. For example, consider a merchant's checkout page with a payment form from a third-party payment service provider (PSP):
+
+```html
+
+
+
+
+```
+
+```html
+
+
+
+
+
+```
+
+There are two trust relations at play:
+
+* between the user and the merchant: the user is willing to pay for the merchant's goods, and
+* between the merchant and the PSP: the merchant leaves the payment processing to the PSP.
+
+The transitive closure may not explicitly hold: the user may not know about the PSP and its role in payment processing.
+
+By enabling `autofill` (and its companion feature `manual-text`) in the `allow` attribute, the merchant enables the user agent to seamlessly autofill the entire credit card form, i.e., the fields in `checkout.html` and `pay.html`.
+
+This mechanism is not limited to a pair of frames. In particular, it also works if the card number, expiration date, and the security code fields are distributed over three separate iframes and `autofill` is enabled in each of them.
+
+### Example 3: multiple origins
+
+Consider the following toy example:
+
+```html
+
+
+
+
+
+```
+
+```html
+
+
+
+```
+
+A user agent may simultaneously autofill form controls in `{a,b,c}.html` about the different origins because `autofill` is enabled in the three documents. The [next section](#security-and-privacy) demonstrates why `autofill` should be enabled only on trusted origins.
+
+## Security and privacy
+
+Intuitively, `autofill` instructs the user agent that a document can be treated as first-party content for the purposes of autofill. On the one hand, this specification of trust for autofill purposes is intended to help user agents protect the user's data from being filled in untrusted documents. On the other hand, when `autofill` is enabled in an untrustworthy document, this positive signal to the user agent may be detrimental to data security. This section discusses attack vectors and mitigations.
+
+### Eavesdropping due to overly permissive policies
+
+Enabling `autofill` in untrusted iframes may indirectly expose data to third parties. In the following example, a malicious ad (`ad.html`) tries to eavesdrop on a legitimate payment form (`pay.html`):
+
+```html
+
+
+
+
+
+```
+
+```html
+
+
+
+
+
+```
+
+```html
+
+
+
+
+
+
+```
+
+User agents should therefore not take `autofill` as license to fill everything. Filling behavior may still need to be specific to the type of data and the involved origins. An obvious example is credentials: origin-bound usernames and passwords should not be autofilled into a cross-origin document. For credit cards, the user agent may run plausibility checks before filling data. An example validity check is that the same credit card number should not be filled in two distinct origins – otherwise, one document may be eavesdropping on the other.
+
+If the embedding document does not trust their own `allow` attributes, they can still override them with the `Permissions-Policy` HTTP header (because a feature [must be enabled](https://w3c.github.io/webappsec-permissions-policy/#algo-define-inherited-policy-in-container) in both the document's permissions policy and the container policy). For example, `Permissions-Policy: autofill=(self "https://psp.example.com")` prevents all origins except for `https://psp.example.com` from inheriting `autofill`.
+
+**Mitigations:**
+
+* User agents should consider the origin of fields and not, for example, fill credentials in third-party documents.
+* Web developers should explicitly allow `autofill` only when needed, and otherwise rely on the default policy.
+* Web servers can restrict the policy with an HTTP header.
+
+### Trusted documents embedded in untrusted documents
+
+A fundamental assumption of this proposal is that trust only propagates downwards. This implies that a trusted document's parent is trusted, too, and as a result, an embedder may be able to eavesdrop on its embeddees like in the [previous section](#eavesdropping-due-to-overly-permissive-policies). The main difference to the previous section is that this case does not require an overly permissive policy.
+
+For example, suppose a malicious website embeds a social media site and the user sees their signed-in state. The user may therefore trust the embeddee and autofill data in the embeddee. With `autofill` enabled in the embedder, the user agent may also include form controls from the embedding document in the scope of the autofill – the embeddee has no means to exclude them.
+
+Arguably, in such a scenario where the embeddee does not prevent being embedded in an iframe (e.g., with the `X-Frame-Options` header or the `frame-ancestors` CSP), clickjacking is a greater problem than potential eavesdropping. Also, like in the [previous section](#eavesdropping-due-to-overly-permissive-policies), the suggested plausibility checks limit the type of data that could be exposed to the parent document.
+
+A fundamental fix would be to make `autofill` opt-in: the embedded document would specify which origins it is willing to inherit `autofill` from. That in turn would require the embeddee to list all legitimate embedders, which is not feasible for, e.g., payment service providers.
+
+**Mitigations:**
+
+* Web pages should limit which parents may embed them in an iframe.
+* Blocking third-party cookies reduces the chance of the user being signed in in an cross-origin iframe.
+* User agents should consider the origin of fields; for example, they should not fill credentials in third-party documents.
+
+### Clickjacking
+
+An attacker who controls the top-level document can use the policy-controlled feature `autofill` to trick the user into unknowingly filling a third-party form, e.g., to transfer money: The attacker embeds an invisible iframe that loads a cross-origin payment form and tricks the user into autofilling a form in the parent document. Due to `autofill`, the user agent may also autofill the embedded document. Next, the attacker clickjacks the user into submitting the embedded form.
+
+An attacker can likely do the same damage without `autofill`. Firstly, they could clickjack the user into (auto)filling the embedded form directly. Secondly, this attack is arguably only relevant when the attacker wants to submit the form from the victim's machine. If the attacker merely wants to steal the victim's autofill data, they manipulate the embedding document directly.
+
+This scenario is a special case of a (purposefully) [overly permissive policy](#eavesdropping-due-to-overly-permissive-policies), so the same mitigations apply.
+
+**Mitigations:**
+
+* User agents should consider the origin of fields and not, for example, fill credentials in third-party documents.
+* Web pages should limit which parents may embed them in an iframe.
+* Web servers can restrict the policy with a HTTP header.
+
+## Relationship of `autofill` and `manual-text`
+
+Whereas text input is directed at the unique currently focused element, a user agent may autofill multiple fields simultaneously. This leads to a subtle difference in the policy-controlled features:
+
+```html
+
+
+
+```
+
+```html
+
+
+
+```
+
+If `autofill` is enabled in two documents `a.html` and `b.html`, the user agent may simultaneously fill form controls in both documents. In user agents where the autofill interaction model is [anchored to a field](#def-field-anchored-interaction-model) (as is the case in, e.g., Chrome, Firefox, Safari), this means an autofill anchored to a form control in `a.html` may also fill form controls in `b.html`.
+
+If `manual-text` is enabled in both documents, it merely means the user can type (etc.) in `a.html` and in `b.html` – but typing in either document won't affect the other document.
diff --git a/images/warning-autofill.png b/images/warning-autofill.png
new file mode 100644
index 0000000..d3cba52
Binary files /dev/null and b/images/warning-autofill.png differ
diff --git a/images/warning-manual-text.png b/images/warning-manual-text.png
new file mode 100644
index 0000000..7ad695a
Binary files /dev/null and b/images/warning-manual-text.png differ
diff --git a/index.bs b/index.bs
index a103b39..e221dfe 100644
--- a/index.bs
+++ b/index.bs
@@ -1,12 +1,12 @@
-Title: The TODO API -Shortname: todo +Title: Policy-controlled features `autofill` and `manual-text` +Shortname: safe-text-input Level: None Status: w3c/UD -Repository: explainers-by-googlers/todo-your-repo-name -URL: https://explainers-by-googlers.github.io/todo-your-repo-name -Editor: TODO: Your Name, Google https://google.com, TODO@google.com -Abstract: TODO: A short description of your spec, one or two sentences. +Repository: explainers-by-googlers/safe-text-input +URL: https://explainers-by-googlers.github.io/safe-text-input +Editor: Christoph Schwering, Google https://google.com, schwering@google.com +Abstract: Two policy-controlled features for safer manual text and autofill input. Markup Shorthands: markdown yes, css no Complain About: accidental-2119 yes, missing-example-ids yes Assume Explicit For: yes diff --git a/manual-text.md b/manual-text.md new file mode 100644 index 0000000..dbed353 --- /dev/null +++ b/manual-text.md @@ -0,0 +1,163 @@ +# Policy-controlled feature `manual-text` + +This proposal is an early design sketch by the Chrome Autofill team to describe the problem below and solicit +feedback on the proposed solution. It has not been approved to ship in Chrome. + +## Participate +- https://github.com/explainers-by-googlers/safe-text-input/issues + +## Table of Contents + + + + + +- [Motivation](#motivation) +- [Goals](#goals) +- [Non-goals](#non-goals) +- [Proposal](#proposal) +- [Text-producing events](#text-producing-events) +- [Use-cases](#use-cases) + - [Disabling text input](#disabling-text-input) + - [Enabling text input](#enabling-text-input) +- [Security and privacy](#security-and-privacy) +- [Relationship of `autofill` and `manual-text`](#relationship-of-autofill-and-manual-text) + + + +## Motivation + +User input on the Web platform is origin-agnostic: any document, even a third party one, can receive input like clicks or keys – not even the embedding document can prevent that. When the user cannot recognize third-party content as such, e.g., because it lacks visual separation as it often does with borderless iframes, this bears the risk of inadvertently disclosing sensitive information to untrusted third parties. + +The underlying problem is that the user's trust in the top-level document implicitly propagates to third-party embeddees. We propose to break this propagation and make the embedder responsible for delegating the ability to receive input to trusted embeddees. We introduce two new [policy-controlled features](https://www.w3.org/TR/permissions-policy/#features) for that purpose. + +Input can come from different sources: directly from the user via input devices like a mouse or keyboard, or from the user agent when it interacts with the website on behalf of the user. Our proposal focuses on two sources that we consider most susceptible to revealing sensitive information: + +* keyboard input (from physical or virtual devices) and +* autofill features, under which we broadly subsume user agents' features that fill one or multiple form control elements with relatively little user interactions. + +This document addresses the first bullet point. An [affiliated document](autofill.md) addresses the other bullet point. + +This proposal is intended as a step towards a web where text user input is disabled by default in cross-origin subframes. + +## Goals + +* Help user agents to warn users before entering text into untrusted origins. + +## Non-goals + +* Suppress non-text keys like arrow or control keys. +* Suppress non-text input such as clicks, taps, swipe patterns, or JavaScript virtual keyboards. + +## Proposal + +We propose a policy-controlled feature `manual-text` which recommends the user agent to suppress text input in documents where the feature is disabled. The precise semantics is: + +If the policy-controlled feature `manual-text` is [disabled](#def-disabled) in a document, the user agent SHOULD NOT [dispatch](https://dom.spec.whatwg.org/#concept-event-dispatch) any [text-producing](#def-text-producing) event in that document. + +An event is text-producing iff it is [trusted](https://w3c.github.io/uievents/#trusted-events) and its [type](https://w3c.github.io/uievents/#event-types-list) is one of `beforeinput`, `input`, `keydown`, `keyup`, `keypress`, `compositionstart`, `compositionupdate`, `compositionend`, `drop`, `paste` and, if it is a key event, the [key attribute value](https://w3c.github.io/uievents-key/#key-attribute-value) is a [key string](https://w3c.github.io/uievents-key/#key-string) other than `" "` (Space, `U+0020`). + +An event is dispatched in a document when it is [dispatched](https://dom.spec.whatwg.org/#concept-event-dispatch) to a target whose [node document](https://dom.spec.whatwg.org/#concept-node-document) is that document. + +A [policy-controlled feature](https://www.w3.org/TR/permissions-policy/#features) is disabled in a document iff the result of executing [Is feature enabled in document for origin?](https://w3c.github.io/webappsec-permissions-policy/#is-feature-enabled) on the feature, the document, and the document's [origin](https://dom.spec.whatwg.org/#concept-document-origin) is `"Disabled"`. + +The [default allowlist](https://www.w3.org/TR/permissions-policy/#default-allowlists) is `'self'`. + +## Text-producing events + +The [definition](#def-text-producing)'s intention is to denylist all specified events that produce characters, but to tolerate keys that are often used for navigation and similar non-text-producing actions. + +In particular, [control keys](https://w3c.github.io/uievents-key/#keys-modifier) like `"Control"`, `"Alt"`, `"Shift"` and [navigation keys](https://w3c.github.io/uievents-key/#keys-navigation) like `"ArrowUp"`, `"ArrowDown"` do not qualify as text-producing events (because these values are not [key strings](https://w3c.github.io/uievents-key/#key-string) but [named key attribute values](https://www.w3.org/TR/uievents-key/#named-key-attribute-value)). + +As somewhat special cases, the definition also tolerates `" "` (Space, `U+0020`) and `"Enter"` and `"Tab"`. The motivation here is that even though these keys produce characters, by themselves they do not reveal meaningful text and their [specified](https://w3c.github.io/uievents/#keydown) default actions are essential for keyboard-based browsing. + +Many browsers attach custom default behavior to ordinary characters if a modifier is pressed. For example, `"P"` with `"Control"` held down commonly brings up a print dialog. These key events still qualify as text-producing because a malicious website could trick the user into holding down `"Control"` while typing and [cancels](https://dom.spec.whatwg.org/#set-the-canceled-flag) the default events. + +## Use-cases + +### Disabling text input + +Cross-origin iframes should often be allowed to present data to the user, but not to receive data from the user. For example, consider a news website that embeds a cross-origin advertisement: + +```html + + + + + +``` + +```html + + + + +``` + +It is clearly not desirable for the user to enter their username or password for the news website in the third-party ad frame. + +Indeed, `manual-text` is disabled in `ad.html` since the document is cross-origin and the default allowlist is `'self'`. (The website can also make this explicit by adding an[allow attribute](https://w3c.github.io/webappsec-permissions-policy/#iframe-allow-attribute)
to theiframe
element:allow="manual-text 'none'"
.) + +Therefore, a user agent should not [dispatch](#def-dispatched) [text-producing events](#def-text-producing) events – e.g., text input from the keyboard – in `ad.html`. + +Browsers may prefer to display autofill suggestions and include a warning to the user. As an example, such a warning could look as follows: + +![The user agent warns the user that text input may expose data to potentially untrustworthy parties.](images/warning-manual-text.png) + +To prevent major breaking changes, we recommend that user agents ramp up the consequences of `manual-text `incrementally. For example, the rollout could proceed in three stages: + +1. Dispatch text-producing events but inform the web developer (e.g., in the JavaScript console) if `manual-text` is disabled. +2. Dispatch text-producing events but warn the user if `manual-text` is disabled. +3. Do not dispatch text-producing events if `manual-text` is disabled. + +### Enabling text input + +In some cases, text input is legitimate in cross-origin iframes. A common example are payment forms, which intentionally live in cross-origin iframes to isolate their contents. For example, consider a merchant's checkout page with a payment form from a third-party payment service provider (PSP): + +```html + + + + +``` + +```html + + + + + +``` + +There are two trust relations at play: + +* between the user and the merchant: the user is willing to pay for the merchant's goods, and +* between the merchant and the PSP: the merchant leaves the payment processing to the PSP. + +The transitive closure may not explicitly hold: the user may not know about the PSP and its role in payment processing. + +By enabling `manual-text` (and its companion feature `autofill`) in the `allow` attribute, the merchant enables the user to type in the credit card form, i.e., the fields in `checkout.html` and `pay.html`. + +## Security and privacy + +`manual-text` is expected to strictly improve security and privacy on the web by protecting users from entering text in untrusted documents. + +## Relationship of `autofill` and `manual-text` + +Whereas text input is directed at the unique currently focused element, a user agent may autofill multiple fields simultaneously. This leads to a subtle difference in the policy-controlled features: + +```html + + + +``` + +```html + + + +``` + +If `autofill` is enabled in two documents `a.html` and `b.html`, the user agent may simultaneously fill form controls in both documents. In user agents where the autofill interaction model is anchored to a field (as is the case in, e.g., Chrome, Firefox, Safari), this means an autofill anchored to a form control in `a.html` may also fill form controls in `b.html`. + +If `manual-text` is enabled in both documents, it merely means the user can type (etc.) in `a.html` and in `b.html` – but typing in either document won't affect the other document.