<?xml version="1.0" encoding="utf-8"?>
<?xml-model href="rfc7991bis.rnc"?>
<!-- <?xml-stylesheet type="text/xsl" href="rfc2629.xslt" ?> -->


<!DOCTYPE rfc [
  <!ENTITY nbsp    "&#160;">
  <!ENTITY zwsp   "&#8203;">
  <!ENTITY nbhy   "&#8209;">
  <!ENTITY wj     "&#8288;">
]>

<rfc
  xmlns:xi="http://www.w3.org/2001/XInclude"
  category="std"
  docName="draft-soni-protocol-handler-well-known-uri-00"
  ipr="trust200902"
  submissionType="IETF"
  xml:lang="en"
  version="3">

  <front>
    <title abbrev="Well-Known Web-Based Protocol Handlers">Discovery of Well-Known Web-Based Protocol Handlers</title>

    <seriesInfo name="Internet-Draft" value="draft-soni-protocol-handler-well-known-uri-00"/>
   
    <author fullname="Soni Lasso Terense" initials="S." surname="Lasso">
      <address>
        <email>fakedme@gmail.com</email>
        <uri>https://soniex2.autistic.space/</uri>
      </address>
    </author>
   
    <date year="2023"/>

    <area>art</area>
    <workgroup>Internet Engineering Task Force</workgroup>

    <abstract>
      <t>This document defines a well-known URI for opening URLs in arbitrary, user-provided web domains, as if the domain were a web-based protocol handler.</t>
    </abstract>
 
  </front>

  <middle>
    
    <section>
      <name>Introduction</name>
      <t>The recent growth of the Fediverse <xref target="W3C.activitypub" /> has highlighted a need for a quick and simple mechanism for opening URLs <xref target="WHATWG-URL" /> across instances.  This specification defines a well-known URI for such purpose with the desired properties: low bandwidth cost, and low latency cost.</t>
    </section>
      
    <section>
      <name>Terminology</name>
      <t>The key words "MUST", "MUST NOT", "REQUIRED", "SHALL",
        "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT
        RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be
        interpreted as described in BCP 14 <xref target="RFC2119"/>
        <xref target="RFC8174"/> when, and only when, they appear in
        all capitals, as shown here.</t>
      <t>The use of URL throughout this document refers to the WHATWG URL Standard <xref target="WHATWG-URL" />.  The use of URI refers to BCP 190 <xref target="RFC8820" />.</t>
    </section>
    
    <section>
      <name>Example Uses of Well-Known Web-Based Protocol Handlers</name>
      <section>
        <name>Fediverse Instance Interactions</name>
        <t>Suppose a Fediverse instance has the ability to display public posts to visiting users.  Someone
          might share a link to a public post from said instance, say <tt>https://public.example/post/foo</tt>.  Visiting users from other instances can click
          a "reply" or other interaction button, and when doing so, they are greeted with a dialog asking
          them for their instance domain.  Once they fill out the dialog, they get navigated to the well-known web-based
          protocol handler for their instance, say <tt>https://users.example/.well-known/protocol-handler?target=https%3A%2F%2Fpublic.example%2Fpost%2Ffoo</tt>,
          where they can interact from their instance with the post.  This workflow is demonstrated in <xref target="fedi-start" /> through <xref target="fedi-end" />.</t>
        <figure anchor="fedi-start">
          <name>Browsing the public post directly</name>
          <artwork type="ascii-art" alt="Browser window navigated to https://public.example/post/foo, showing a post by 'Public User' with the contents 'Hi there! Welcome to my instance!'.  Underneath the post, the buttons 'Reply', 'Boost', and 'Like' are shown, with 'Reply' selected.">
            <![CDATA[
 +-------------------------------------------------------------+
 | https://public.example/post/foo                             |
 +-------------------------------------------------------------+
 | Public User said:                                           |
 | Hi there!                                                   |
 |                                                             |
 | [Reply] |Boost| |Like|                                      |
 +-------------------------------------------------------------+
            ]]>
          </artwork>
        </figure>
        <figure>
          <name>The interaction dialog, which shows up when clicking "reply", already filled out</name>
          <artwork type="ascii-art" alt="Browser window navigated to https://public.example/post/foo, showing an interaction dialog.  The interaction dialog asks the user for an instance, and the user has filled it in with 'users.example'.">
            <![CDATA[
 +-------------------------------------------------------------+
 | https://public.example/post/foo                             |
 +-------------------------------------------------------------+
 | Public  +-----------------------------------------+         |
 | Hi ther | To reply to this post, please type      |         |
 |         | your fediverse instance domain below:   |         |
 | |Reply| | Domain: [users.example____]             |         |
 |         | |Confirm|  |Cancel|                     |         |
 |         +-----------------------------------------+         |
 +-------------------------------------------------------------+
            ]]>
          </artwork>
        </figure>
        <figure anchor="fedi-end">
          <name>The post, now seen from users.example</name>
          <artwork type="ascii-art" alt="Browser window navigated to https://users.example/.well-known/protocol-handler?target=https%3A%2F%2Fpublic.example%2Fpost%2Ffoo, showing the post by 'Public User from public.example'.  Underneath the post, the buttons 'Reply', 'Boost', and 'Like' are shown, with 'Reply' selected.">
            <![CDATA[
 +-------------------------------------------------------------+
 | https://users.example/.well-known/protocol-handler?target=h |
 | ttps%3A%2F%2Fpublic.example%2Fpost%2Ffoo                    |
 +-------------------------------------------------------------+
 | Public User from public.example said:                       |
 | Hi there!                                                   |
 |                                                             |
 | [Reply] |Boost| |Like|                                      |
 +-------------------------------------------------------------+
            ]]>
          </artwork>
        </figure>
      </section>
      <section>
        <name>Web-Based Feed Readers</name>
        <t>Suppose a website provides an Atom feed <xref target="RFC4287" />.  A visiting user wants to open the Atom feed with their favorite
          web-based feed reader.  The user clicks the "Atom feed" button and is prompted for their web-based feed reader.  They fill out the prompt
          and get navigated to the well-known web-based protocol handler for their feed reader, say, <tt>https://feedreader.example/.well-known/protocol-handler?target=feed%3A%2F%2Fwebsite.example%2Findex.atom</tt>,
          where they can browse and/or subscribe to the Atom feed.  This workflow is demonstrated in <xref target="feed-start" /> through <xref target="feed-end" />.</t>
        <figure anchor="feed-start">
          <name>Browsing the website</name>
          <artwork type="ascii-art" alt="Browser window navigated to https://website.example/index.html, showing 'Recent Posts', with the only entry being 'Hello world!'.  Underneath the post list, the button 'Atom Feed' is shown, selected.">
            <![CDATA[
 +-------------------------------------------------------------+
 | https://website.example/index.html                          |
 +-------------------------------------------------------------+
 | Recent posts:                                               |
 | - Hello world!                                              |
 |                                                             |
 | [Atom Feed]                                                 |
 +-------------------------------------------------------------+
            ]]>
          </artwork>
        </figure>
        <figure>
          <name>The feed dialog, which shows up when clicking "Atom Feed", already filled out</name>
          <artwork type="ascii-art" alt="Browser window navigated to https://website.example/index.html, showing an interaction dialog.  The interaction dialog asks the user for a feed reader, and the user has filled it in with 'feedreader.example'.">
            <![CDATA[
 +-------------------------------------------------------------+
 | https://website.example/index.html                          |
 +-------------------------------------------------------------+
 | Recent  +-----------------------------------------+         |
 | - Hello | To view this feed, please type your     |         |
 |         | feed reader's domain below:             |         |
 | |Atom f | Domain: [feedreader.example____]        |         |
 |         | |Confirm|  |Cancel|                     |         |
 |         +-----------------------------------------+         |
 +-------------------------------------------------------------+
            ]]>
          </artwork>
        </figure>
        <figure anchor="feed-end">
          <name>The Atom feed, now seen from feedreader.example</name>
          <artwork type="ascii-art" alt="Browser window navigated to https://feedreader.example/.well-known/protocol-handler?target=feed%3A%2F%2Fwebsite.example%2Findex.atom, showing posts from 'https://website.example/index.atom'.  'Hello world!' is the only post shown.">
            <![CDATA[
 +-------------------------------------------------------------+
 | https://feedreader.example/.well-known/protocol-handler?tar |
 | get=feed%3A%2F%2Fwebsite.example%2Findex.atom               |
 +-------------------------------------------------------------+
 | Posts from https://website.example/index.atom               |
 | - Hello world!                                              |
 +-------------------------------------------------------------+
            ]]>
          </artwork>
        </figure>
      </section>
      <section>
        <name>Webmail Prompt as an Alternative to Bare <tt>mailto:</tt></name>
        <t>Suppose a website wants to allow users to contact the website author.  A visiting user clicks the "email" button and is prompted for their email
          address.  After filling it out, the user gets navigated to the well-known web-based protocol handler for their email address, say, <tt>https://webmail.example/.well-known/protocol-handler?target=mailto%3Aauthor%40website.example%3Ffrom%3Dvisitinguser%40webmail.example</tt>.  The webmail uses
          the embedded <tt>from</tt> value to automatically select the correct user account from the multi-account switcher.  This workflow is demonstrated in <xref target="email-start" /> through <xref target="email-end" />.</t>
        <aside>
          <t>This example has the webmail interpreting the <tt>from</tt> value in a <tt>mailto</tt> URI, in apparent contradiction to the requirements in the <tt>mailto</tt> specification <xref target="RFC6068" />.  However, it is not being interpreted as a header value, but as a suggestion to the webmail's account switcher.</t>
        </aside>
        <figure anchor="email-start">
          <name>Browsing the website</name>
          <artwork type="ascii-art" alt="Browser window navigated to https://website.example/index.html, showing 'Recent Posts', with the only entry being 'Hello world!'.  Underneath the post list, the button 'Contact the Author' is shown, selected.">
            <![CDATA[
 +-------------------------------------------------------------+
 | https://website.example/index.html                          |
 +-------------------------------------------------------------+
 | Recent posts:                                               |
 | - Hello world!                                              |
 |                                                             |
 | [Contact the Author]                                        |
 +-------------------------------------------------------------+
            ]]>
          </artwork>
        </figure>
        <figure>
          <name>The contact dialog, which shows up when clicking "Contact the Author", already filled out</name>
          <artwork type="ascii-art" alt="Browser window navigated to https://website.example/index.html, showing an interaction dialog.  The interaction dialog asks the user for an email, and the user has filled it in with 'visitinguser@webmail.example'.">
            <![CDATA[
 +-------------------------------------------------------------+
 | https://website.example/index.html                          |
 +-------------------------------------------------------------+
 | Recent  +-----------------------------------------+         |
 | - Hello | To contact the author, please type your |         |
 |         | email: [visitinguser@webmail.example__] |         |
 | [Contac | |Confirm|  |Cancel|                     |         |
 |         +-----------------------------------------+         |
 +-------------------------------------------------------------+
            ]]>
          </artwork>
        </figure>
        <figure anchor="email-end">
          <name>The user's webmail</name>
          <artwork type="ascii-art" alt="Browser window navigated to https://webmail.example/.well-known/protocol-handler?target=mailto%3Aauthor%40website.example%3Ffrom%3Dvisitinguser%40webmail.example, composing a message to 'author@website.example'.">
            <![CDATA[
 +-------------------------------------------------------------+
 | https://webmail.example/.well-known/protocol-handler?target |
 | =mailto%3Aauthor%40website.example%3Ffrom%3Dvisitinguser%40 |
 | webmail.example                                             |
 +-------------------------------------------------------------+
 | To: |author@website.example    |                            |
 | Subject: [______________]                                   |
 | Message:                                                    |
 | +--------------------------------------+                    |
 | |                                      |                    |
 | |                                      |                    |
 | |                                      |                    |
 | +--------------------------------------+                    |
 | |Send| |Save Draft| |Cancel|                                |
 +-------------------------------------------------------------+
            ]]>
          </artwork>
        </figure>
      </section>
    </section>

    <section>
      <name>Semantics of the Well-Known Web-Based Protocol Handler</name>
      <t>The well-known web-based protocol handler <bcp14>SHALL</bcp14> accept a <tt>target</tt> query parameter.  This query parameter <bcp14>SHALL</bcp14> carry an absolute-URL-with-fragment-string; see <xref target="WHATWG-URL" relative="#url-writing" section="4.3" />.  No restrictions are placed on the URL's scheme.  The choice to use the WHATWG URL specification allows the well-known web-based protocol handler to optionally be registered with the browser, should the website choose to do so, as per <xref target="WHATWG-HTML" relative="system-state.html#custom-handlers" section="8.9.1.4" />.</t>
      <t>The well-known web-based protocol handler is explicitly intended for navigation: a web browser will navigate to it when using it.  It is up to the server to decide how to handle the given URL, but note <xref target="Security" format="title" />.</t>
      <t>To support probing, a server <bcp14>MAY</bcp14> opt to return 4xx-responses for URL schemes it doesn't recognize or doesn't accept.  It is <bcp14>NOT RECOMMENDED</bcp14> to use generic schemes (<tt>http</tt>, <tt>https</tt>, and the like), as they convey less information when probing.</t>
    </section>
    
    <section anchor="IANA">
      <name>IANA Considerations</name>
      <t>This specification registers the "protocol-handler" well-known URI in the "well-known URIs" registry as defined by RFC 8615 <xref target="RFC8615"/>.</t>
      <t>URI suffix:  protocol-handler</t>
      <t>Change controller:  IETF</t>
      <t>Specification document(s):  TBD</t>
      <t>Status:  permanent</t>
      <t>Related information:  Not applicable.</t>
    </section>
    
    <section anchor="Security">
      <name>Security Considerations</name>
      <t>The specified well-known URI is a simple navigable resource, and the security considerations relevant to any navigable resource apply.  Nevertheless, we highlight the following two vulnerabilities and recommendations as they are particularly relevant.</t>
      <section>
        <name>Open Redirect</name>
        <t>An open redirect attack occurs when an attacker uses an open redirect on a legitimate website in order to trick an unsuspecting user into visiting the attacker's phishing website.</t>
          <t>Due to the nature of the well-known URI, common mitigations such as checking <tt>Referer</tt>, <tt>Origin</tt>, and other headers, are not available here.  Where possible, the provided URL <bcp14>SHOULD</bcp14> be opened within the scope of the well-known resource.  Otherwise, the user <bcp14>MUST</bcp14> be notified of scope changes and be given the option to confirm or deny them.</t>
      </section>
      <section>
        <name>Improper Authorization in Handler for Custom URL Scheme</name>
        <t>Some URLs may be used to carry actions.  An attacker may include malicious actions in such URLs.  Since this endpoint is navigable, an attacker can simply open it, sometimes even without user intervention.</t>
        <t>Servers implementing this well-known URI <bcp14>MUST NOT</bcp14> automatically execute actions based on the target URL.  Ideally, servers <bcp14>SHOULD</bcp14> reject/ignore these actions altogether, and let the user execute the action in the interface they are presented with, as it's not uncommon for users to simply click "yes" or "confirm" in an attempt to dismiss prompts.  In some cases, for example for message composition URLs (<tt>mailto</tt>, etc), this may simply not be possible; in these cases the server can prompt the user before executing the action.</t>
      </section>
    </section>
  </middle>

  <back>
    <references>
      <name>References</name>

      <references>
        <name>Normative References</name>
        
        <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.2119.xml"/>
        <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.8174.xml"/>
        <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.8615.xml"/>
        <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.8820.xml"/>

        <reference anchor="WHATWG-URL" target="https://uri.spec.whatwg.org/">
          <front>
            <title>URL Standard</title>
            <author initials="A." surname="van Kesteren" fullname="Anne van Kesteren">
              <organization>WHATWG</organization>
            </author>
            <date day="24" month="May" year="2023">Living Standard</date>
          </front>
        </reference>       
        
      </references>
 
      <references>
        <name>Informative References</name>

        <xi:include href="https://bib.ietf.org/public/rfc/bibxml4/reference.W3C.activitypub.xml"/>
        <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.4287.xml"/>
        <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.6068.xml"/>

        <reference anchor="WHATWG-HTML" target="https://html.spec.whatwg.org/multipage/">
          <front>
            <title>HTML Standard</title>
            <author initials="A." surname="van Kesteren" fullname="Anne van Kesteren">
              <organization>WHATWG</organization>
            </author>
            <date day="29" month="June" year="2023">Living Standard</date>
          </front>
        </reference>       
        
      </references>
    </references>
 </back>
</rfc>
