<?xml version="1.0" encoding="US-ASCII"?>
<!-- This template is for creating an Internet Draft using xml2rfc,
     which is available here: http://xml.resource.org. -->
<!DOCTYPE rfc SYSTEM "rfc2629.dtd" [
<!-- One method to get references from the online citation libraries.
     There has to be one entity for each item to be referenced. 
     An alternate method (rfc include) is described in the references. -->
<!ENTITY RFC5246 SYSTEM "http://xml.resource.org/public/rfc/bibxml/reference.RFC.5246.xml">
<!ENTITY RFC6146 SYSTEM "http://xml.resource.org/public/rfc/bibxml/reference.RFC.6146.xml">
<!ENTITY RFC6265 SYSTEM "http://xml.resource.org/public/rfc/bibxml/reference.RFC.6265.xml">
<!ENTITY RFC6555 SYSTEM "http://xml.resource.org/public/rfc/bibxml/reference.RFC.6555.xml">
<!ENTITY RFC6749 SYSTEM "http://xml.resource.org/public/rfc/bibxml/reference.RFC.6749.xml">
<!ENTITY RFC6824 SYSTEM "http://xml.resource.org/public/rfc/bibxml/reference.RFC.6824.xml">
<!ENTITY RFC6883 SYSTEM "http://xml.resource.org/public/rfc/bibxml/reference.RFC.6883.xml">
<!ENTITY RFC6888 SYSTEM "http://xml.resource.org/public/rfc/bibxml/reference.RFC.6888.xml">
<!ENTITY I-D.ietf-httpbis-http2 PUBLIC "" "http://xml.resource.org/public/rfc/bibxml3/reference.I-D.ietf-httpbis-http2.xml">
<!ENTITY I-D.ietf-softwire-map-t PUBLIC "" "http://xml.resource.org/public/rfc/bibxml3/reference.I-D.ietf-softwire-map-t.xml">
]>
<?xml-stylesheet type='text/xsl' href='rfc2629.xslt' ?>
<!-- used by XSLT processors -->
<!-- For a complete list and description of processing instructions (PIs), 
     please see http://xml.resource.org/authoring/README.html. -->
<!-- Below are generally applicable Processing Instructions (PIs) that most I-Ds might want to use.
     (Here they are set differently than their defaults in xml2rfc v1.32) -->
<?rfc strict="yes" ?>
<!-- give errors regarding ID-nits and DTD validation -->
<!-- control the table of contents (ToC) -->
<?rfc toc="yes"?>
<!-- generate a ToC -->
<?rfc tocdepth="3"?>
<!-- the number of levels of subsections in ToC. default: 3 -->
<!-- control references -->
<?rfc symrefs="yes"?>
<!-- use symbolic references tags, i.e, [RFC2119] instead of [1] -->
<?rfc sortrefs="yes" ?>
<!-- sort the reference entries alphabetically -->
<!-- control vertical white space 
     (using these PIs as follows is recommended by the RFC Editor) -->
<?rfc compact="yes" ?>
<!-- do not start each main section on a new page -->
<?rfc subcompact="no" ?>
<!-- keep one blank line between list items -->
<!-- end of list of popular I-D processing instructions -->
<rfc category="info" docName="draft-vyncke-v6ops-happy-eyeballs-cookie-01"
     ipr="trust200902">
  <!-- ***** FRONT MATTER ***** -->

  <front>
    <!-- The abbreviated title is used in the page header - it is only necessary if the 
         full title is longer than 39 characters -->

    <title abbrev="HTTP States with Multiple Addresses">HTTP State Management
    Mechanisms with Multiple Addresses User Agents</title>

    <!-- add 'role="editor"' below for the editors if appropriate -->

    <author fullname="Eric Vyncke" initials="E" surname="Vyncke">
      <organization>Cisco</organization>

      <address>
        <postal>
          <street>De Kleetlaan 6a</street>

          <city>Diegem</city>

          <country>Belgium</country>

          <code>1831</code>
        </postal>

        <phone>+32 2 778 4677</phone>

        <email>evyncke@cisco.com</email>
      </address>
    </author>

    <date day="6" month="March" year="2015"/>

    <!-- If the month and year are both specified and are the current ones, xml2rfc will fill 
         in the current day for you. If only the current year is specified, xml2rfc will fill 
	 in the current day and month for you. If the year is not the current one, it is 
	 necessary to specify at least a month (xml2rfc assumes day="1" if not specified for the 
	 purpose of calculating the expiry date).  With drafts it is normally sufficient to 
	 specify just the year. -->

    <!-- Meta-data Declarations -->

    <area>Operations and Management</area>

    <workgroup>IPv6 Operations</workgroup>

    <!-- WG name at the upperleft corner of the doc,
         IETF is fine for individual submissions.  
	 If this element is not present, the default is "Network Working Group",
         which is used by the RFC Editor as a nod to the history of the IETF. -->

    <keyword>IPv6</keyword>

    <keyword>Cookie</keyword>

    <keyword>Operational</keyword>

    <keyword>Access token</keyword>

    <keyword>multiple addresses</keyword>

    <!-- Keywords will be incorporated into HTML output
         files in a meta tag but they have no effect on text or nroff
         output. If you submit your draft to the RFC Editor, the
         keywords will be used for the search engine. -->

    <abstract>
      <t>HTTP servers usually save session states in their persistent storage
      indexed by session cookies generated by the HTTP servers. It is up to
      the HTTP user-agent to send this session cookie on each HTTP request.
      Some HTTP servers check whether the cookie is associated with the HTTP
      user-agent by the means of the user-agent IP address. Everything linking
      a state to an IP address (such as OAuth access code) to an IP address
      has the same issue.</t>

      <t>If the Happy Eyeball mechanism is used to select between IPv6 and
      IPv4, it may happen that while using the same HTTP server, some HTTP
      requests are done over IPv6 and the others over IPv4, which leads to two
      different sets of session states in the HTTP server. This has the
      consequence of inconsistencies at the HTTP server.</t>

      <t>The only purpose of this document is to document this issue in more
      details than in section 8.2 of RFC 6883 including security
      considerations and mitigations.</t>

      <t>A similar problem arises with the use of non RFC 6888 compliant
      Carrier-Grade NAT (CGN) devices used to access an IPv4-only HTTP server
      or HTTP user-agent using multi-homing.</t>
    </abstract>
  </front>

  <middle>
    <section title="HTTP Session Management with HTTP Cookie">
      <t>HTTP requests are basically stateless, therefore if a HTTP server
      requires to have some states associated to a HTTP user-agent (such as
      user name, login state, history, shopping basket, ...), there is a need
      to conserve those states. This is usually done by using a HTTP cookie
      (see also <xref target="RFC6265">RFC6265</xref>) identifying the
      session; also called "session state cookie".</t>

      <t>This session state cookie is generated by the HTTP server at the very
      first HTTP request from a HTTP user-agent. The cookie is usually opaque
      (often a random number) and has no semantic except as being an index
      within the persistent storage of the HTTP server. This index is used to
      access the complete state of the user-agent. This mechanism is secure if
      the cookie is transferred with confidentiality between the server and
      the user-agent. If the cookie transfer and storage are not secured, then
      any hostile user-agent can reuse this cookie to access the full original
      session states (including shopping basket, payment details, ...); this
      attack is called 'session cookie stealing'. This attack can happen if
      the HTTP traffic is intercepted by a man-in-the-middle attack but a good
      use of Transport Level Security <xref target="RFC5246">RFC5246</xref>
      can prevent it. The attack can also happen with some hostile scripting
      or other pieces of malware running on the user agent, that could copy
      and send the session cookie to the hostile user-agent; hence, it is not
      enough to use TLS to secure the session cookies.</t>

      <t>Some HTTP applications link the user-agent IP address (whether IPv6
      or IPv4) to the session state, probably for additional security checks
      in order to prevent session cookie stealing. This link leads to some
      issues in a dual-stack world which are described in this document.</t>

      <t>The author knows about at least two large web sites having this
      problem. It was so severe that those sites which were dual-stack had to
      move back to being IPv4-only... until the application and its security
      is updated.</t>

      <section title="Other Use of Session Cookies">
        <t>Beside the use of session cookies by the HTTP server to keep states
        on the server, the very same cookie is also sometimes used by Server
        Load Balancing (SLB) mechanism to ensure that all HTTP requests from
        the same user-agent (even if behind a NAT) are always sent to the same
        physical HTTP server. This is required if the server persistent
        storage is local to the server and is not shared by all the physical
        servers behind the SLB.</t>
      </section>

      <section title="new section">
        <t>Actually the problem is more generic than the session cookie,
        everything linking a state to an IP address has the same issue. This
        includes <xref target="RFC6749">OAuth</xref> access tokens, bearer
        tokens, ... but also other mechanisms such as rate limiting per IP
        address or access control per IP address (for instance a captive
        portal for a guest net).</t>
      </section>
    </section>

    <section title="Issues">
      <t>Similar issues can be caused by Happy Eyeball <xref
      target="RFC6555">RFC6555</xref>, Carrier-Grade NAT (CGN) and having
      multiple interface or being multi-homed.</t>

      <section anchor="happyeyeballs" title="Happy Eyeballs Issue">
        <t>When a HTTP user-agent uses the Happy Eyeball mechanism to access a
        HTTP server, then, part of the HTTP requests can happen over IPv6 and
        another part over IPv4 if the latency between IPv4 and IPv6 varies
        quickly over time. If there is a link between the session cookie and
        the user-agent IP address, then upon the first change of IP protocol
        version, the states associated to the cookie will be invalidated and
        will be deleted. Here is an example:<list style="numbers">
            <t>User-agent with IPv4 address, ADDR4, connect to the server by
            using IPv4 because IPv6 is slower; the first request does not have
            any HTTP cookie;</t>

            <t>Server generates a new cookie C4 and stores in its persistent
            storage that C4 is associated with address ADDR4;</t>

            <t>User-agent continues his/her session using IPv4, on each new
            request the HTTP server receives the cookie C4 and checks that the
            user-agent address is indeed ADDR4;</t>

            <t>Latency of IPv6 changes and becomes now faster than IPv4;</t>

            <t>User-agent now uses its IPv6 address, ADDR6, to connect to the
            same server and continues to use the same cookie C4 as the server
            name is unchanged;</t>

            <t>The server receives the HTTP request with the C4 cookie and
            checks whether C4 is associated with ADDR6 which is not the
            case... All session states are deleted and a new cookie, C6, is
            generated and associated to the IPV6 address ADDR6;</t>

            <t>The end-user becomes frustrated because he/she has to restart
            his/her complete session from the beginning.</t>
          </list></t>

        <t>This cookie invalidation may have some security benefit but it
        actually prevents a host using Happy Eyeballs to have a persistent
        session with a dual-stack HTTP server; with painful consequences for
        the user-experience: disconnection, loss of shopping basket, ...</t>
      </section>

      <section title="Carrier-Grade NAT Issue">
        <t><xref target="RFC6888">RFC6888</xref> describes the CGN
        requirements but not all CGN implement them. Some CGN in the real
        world have a pool of IPv4 addresses and do not always use the same
        public IPv4 address for all requests from a CGN client. This obviously
        leads to the same problem as in section <xref
        target="happyeyeballs"/>. This will happen for IPv4-only HTTP
        servers.</t>

        <t>Whether the CGN is used by IPv4 clients or by IPv6 clients (via
        NAT64 <xref target="RFC6146">RFC6146</xref>)does not make any
        difference to the problem. The use of the address family translation
        by MAP-T <xref target="I-D.ietf-softwire-map-t">MAP-T</xref> does not
        suffer from this issue for IPv4-only HTTP servers since one subscriber
        is restricted to several layer-4 ports from a single IPv4 address.</t>
      </section>

      <section title="Multiple Interfaces Issue">
        <t>When the HTTP user-agent has multiple interfaces, for example 3GPP
        and Wi-Fi, the preferred IP address depends on the WiFi or 3GPP
        availability. In this case, a similar issue to <xref
        target="happyeyeballs"/> also happens as the session cookie can be
        linked first to the Wi-Fi IP address then when the user-agent looses
        its Wi-Fi connectivity the session cookie will be overwritten by a new
        session cookie linked to the 3GPP address.</t>

        <t>Whether the user-agent uses IPv4-only, IPv6-only or dual-stack has
        no impact on the issue.</t>
      </section>
    </section>

    <section title="Mitigations">
      <t>The obvious mitigation for this issue is NOT to link any HTTP state
      management (including cookies) to any IP address of the HTTP user-agent
      at the risk of increasing the risk of "session cookie stealing".</t>

      <t>The author also believes that:<list>
          <t>Multipath TCP <xref target="RFC6824">RFC6824</xref> hides
          completely the set of addresses of the client to the application.
          Only the first subflow's IP addresses are exposed to the
          application, even if a later subflow uses a different address
          family; so, any session cookie will be permanently linked to the
          first IP address used by the HTTP user-agent;</t>

          <t>HTTP/2 <xref target="I-D.ietf-httpbis-http2"/> multiplexes
          multiple HTTP sessions over a single TCP connection, therefore,
          Happy Eyeball (or bad CGN) sees only one TCP connection and a change
          of IP address will never occur during the lifetime of this TCP
          connection.</t>
        </list></t>
    </section>

    <section title="IANA Considerations">
      <t>This document contains no IANA considerations.</t>
    </section>

    <section title="Security Considerations">
      <t>The association of the session cookie with the user-agent IP address
      has some security value as it can help prevent "session cookie stealing"
      in some limited situations; this benefit should be balanced with the
      lack of persistent session and the remaining vulnerability if the HTTP
      session can be intercepted by a man-in-the-middle attack. Moreover with
      more and more CGN being deployed, linked a session cookie to an IP
      address shared by hundreds of subscribers is less effective as the
      cookie could be reused by any subscribers using the same shared public
      IP address.</t>
    </section>

    <section title="Acknowledgements">
      <t>The author would like to thank Brian Carpenter, Ray Hunter, Jeroen
      Massar, Dan Metzler, Erik Nygren, Mark ZZZ Smith, Joe Touch, Dan Wing
      and Andrew Yourtchenko for some discussions on this topic. Of course,
      <xref target="RFC6883">RFC6883</xref> has already mentionned this issue
      without many details.</t>
    </section>
  </middle>

  <!--  *****BACK MATTER ***** -->

  <back>
    <references title="Informative References">
      &RFC5246;

      &RFC6265;

      &RFC6146;

      &RFC6555;

      &RFC6749;

      &RFC6824;

      &RFC6883;

      &RFC6888;

      &I-D.ietf-softwire-map-t;

      &I-D.ietf-httpbis-http2;
    </references>
  </back>
</rfc>
