<?xml version="1.0" encoding="utf-8"?>
<?xml-model href="rfc7991bis.rnc"?> 

<!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-ietf-tcpm-tcp-ghost-acks-06"
  ipr="trust200902"
  obsoletes=""
  updates=""
  submissionType="IETF"
  xml:lang="en"
  version="3">

  <front>
    <title abbrev="Ghost ACKs Mitigation">Improve TCP Handling of Out-of-Window Packets to Mitigate Ghost ACKs</title>
    <seriesInfo name="Internet-Draft" value="draft-ietf-tcpm-tcp-ghost-acks-06"/> 
    <author fullname="Yepeng Pan" initials="Y." surname="Pan"> 
      <organization>CISPA Helmholtz Center for Information Security</organization>
      <address>
      <email>yepeng.pan@cispa.de</email>
      </address>
    </author>
    <author fullname="Christian Rossow" initials="C." surname="Rossow">
      <organization>CISPA Helmholtz Center for Information Security</organization>
      <address>
      <email>rossow@cispa.de</email>
      </address>
    </author>
    <date month="06" year="2026"/> 
    <area>Transport</area>
    <workgroup>TCPM</workgroup>
    <keyword>TCP</keyword>
    <keyword>TCPM</keyword>
    <keyword>transport layer</keyword>
    <keyword>internet transport</keyword>
    <abstract pn="section-abstract">
      <t indent="0" pn="section-abstract-1">
        Historically, TCP as specified in RFC 793 was threatened 
        by the blind data injection attack because of the loose <tt>SEG.ACK</tt> value validation, where the <tt>SEG.ACK</tt> value of a
        TCP segment is considered valid as long as it does not acknowledge data ahead of what has been sent.
        RFC 5961 improved the input validation by
        shrinking the range of acceptable <tt>SEG.ACK</tt> values in a TCP segment. Later, RFC 9293
        incorporated the updates proposed by RFC 5961 as a TCP stack implementation option.<br></br>

        However, an endpoint that follows the RFC 9293 specifications can still accept a TCP segment containing
        an <tt>SEG.ACK</tt> value acknowledging data that the endpoint has never sent. This document specifies small modifications to the
        way TCP verifies incoming TCP segments' <tt>SEG.ACK</tt> value to prevent TCP from accepting such invalid <tt>SEG.ACK</tt> values.
      </t>
    </abstract>
  </front>

  <middle>
    <section>
      <name>Introduction</name>
      <t>
        TCP as specified in <xref target="RFC0793"/> is widely deployed in today's Internet. 
        Against the threat of the blind data injection attack, <xref section="5" sectionFormat="of" target="RFC5961"/> 
        proposed to improve the validation of the <tt>SEG.ACK</tt> field of incoming TCP segments.
        Currently, <xref target="RFC9293"/> is the latest main document for TCP, which obsoletes <xref target="RFC0793"/> and incorporates the <tt>SEG.ACK</tt> validation proposed by <xref target="RFC5961"/>
        as an optional implementation choice.

        The <tt>SEG.ACK</tt> validation introduced in <xref target="RFC9293"/> (with or without the <xref target="RFC5961"/> implementation choice)
        accepts a certain range of <tt>SEG.ACK</tt> values before <tt>SND.UNA</tt> as duplicate/old ACK values.
        This also applies to connections without data (or with little data) transferred previously.
        Consequently, current <tt>SEG.ACK</tt> validation accepts segments with invalid <tt>SEG.ACK</tt> values that acknowledge data that an endpoint has never sent as "duplicate/old" <tt>SEG.ACK</tt> values (ghost ACKs).
        <br></br>


        This document aims to improve the <tt>SEG.ACK</tt> value validation
        in <xref target="RFC9293"/>, 
        such that TCP would only accept duplicate/old <tt>SEG.ACK</tt> values acknowledging data already sent by the endpoint, eliminating the security risks imposed by ghost ACKs.
      </t>
      
      <section anchor="Terminology">
      <!-- anchor is an optional attribute -->
        <name>Terminology</name>
        <t>The key words "<bcp14>MUST</bcp14>", "<bcp14>MUST NOT</bcp14>",
        "<bcp14>REQUIRED</bcp14>", "<bcp14>SHALL</bcp14>", "<bcp14>SHALL NOT</bcp14>",
        "<bcp14>SHOULD</bcp14>", "<bcp14>SHOULD NOT</bcp14>",
        "<bcp14>RECOMMENDED</bcp14>", "<bcp14>NOT RECOMMENDED</bcp14>",
        "<bcp14>MAY</bcp14>", and "<bcp14>OPTIONAL</bcp14>" 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>TCP terminology should be interpreted as described in <xref target="RFC9293"/>. 
        </t>
      </section>
      <!-- The 'Requirements Language' section is optional -->
    </section>
    
    <section>
      <name>Ghost ACKs</name>
      <t>
      As described in <xref target="RFC9293"/>, when receiving a segment, 
      the endpoint performs checks on the <tt>SEG.ACK</tt> field of the incoming segment.
      
      Suppose the TCP stack has implemented the mitigation for blind data injection attack proposed by <xref section="5" sectionFormat="of" target="RFC5961"/>, 
      an incoming segment whose <tt>SEG.ACK</tt> value satisfies the condition <tt>SND.UNA - MAX.SND.WND =&lt; SEG.ACK =&lt; SND.NXT</tt> is considered acceptable,
      and the segment is further processed.
      
      When the <xref target="RFC5961"/> mitigation is not implemented, an incoming segment with <tt>SEG.ACK =&lt; SND.NXT</tt> is accepted and further processed.
      </t>

      <t>
      However, there are cases where the number of bytes sent by the endpoint is less than <tt>MAX.SND.WND</tt> or 2<sup>31</sup> - 1, and this can result in
      accepting a segment with an <tt>SEG.ACK</tt> value acknowledging bytes the endpoint has never sent.<br/>

      As a concrete example, consider a newly established TCP connection without data transferred during the handshake.
      There is <tt>SND.UNA == SND.NXT == ISS + 1</tt>. 
      In this case, any segments with <tt>SEG.ACK &lt; SND.UNA</tt> acknowledges bytes that the endpoint has never sent, but they are still considered acceptable
      since they satisfy the above <tt>SEG.ACK</tt> validation condition.



    </t>
    </section>


    <section>
      <name>Security Implications of Ghost ACKs</name>

      <t>
        Ghost ACKs allow an attacker to inject payloads into a newly established connection.
        This extends the threat model as described in <xref target="RFC5961"/>, where an off-path attacker can perform injection attacks against an existing foreign connection.
        Ghost ACKs further allow attackers that spoof the TCP handshake to use the spoofed TCP connection and transmit payloads <xref target="SP2024Spoof" format="default" sectionFormat="of" derivedContent="1"/>.
      </t>

    </section>

<section>
<name>Mitigations</name>
<t>TCP stacks <bcp14>MAY</bcp14> implement one of the following two mitigations.
Both mitigation options assume <xref target="RFC5961"/> is already supported by
the TCP stack and improve the <tt>SEG.ACK</tt> validation of received TCP segments.</t>

<section>
<name>Mitigation Option 1 (generic)</name>

<t>TCP stacks that implement this mitigation <bcp14>SHOULD</bcp14> add
the additional boolean state variable <tt>NO_ISS_CHECK</tt> for each
established connection.
This variable <bcp14>SHOULD</bcp14> be initialized to false.
At the beginning of the <tt>SEG.ACK</tt> validation, it <bcp14>SHOULD</bcp14>
be checked if the <tt>ISS</tt> is still needed:</t>
<sourcecode>
if (!NO_ISS_CHECK &amp;&amp; SND.UNA >= ISS + (65535 &lt;&lt; Snd.Wind.Shift)) {
    /* Checking SEG.ACK against ISS is definitely redundant. */
    NO_ISS_CHECK = true;
}
</sourcecode>
<t><tt>Snd.Wind.Shift</tt> is defined in <xref target="RFC7323"/>.
Then a local variable <tt>ACK.MIN</tt> <bcp14>SHOULD</bcp14> be computed,
which is later used to validate the <tt>SEG.ACK</tt>.
It is used to perform the validation, which is stricter.</t>
<sourcecode>
if (NO_ISS_CHECK) {
    /* Check for too old ACKs (RFC 5961, Section 5.2). */
    ACK.MIN = SND.UNA - MAX.SND.WND;
} else {
    if (ISS + 1 > SND.UNA - MAX.SND.WND) {
        /* Checking for ghost ACKs is stricter. */
        ACK.MIN = ISS + 1;
    } else {
        /* Checking for too old ACKs (RFC 5961, Section 5.2) is stricter. */
        ACK.MIN = SND.UNA - MAX.SND.WND;
    }
}
</sourcecode>
<t>Finally the validation of <tt>SEG.ACK</tt> <bcp14>SHOULD</bcp14> be performed:</t>
<sourcecode>
if (SEG.ACK &lt; ACK.MIN) {
    send_challenge_ack;
    return;
}
</sourcecode>
</section>

<section>
<name>Mitigation Option 2 (requires <xref target="RFC4898"/> support)</name>
<t>TCP stacks that support the <tt>tcpEStatsAppHCThruOctetsAcked</tt> counter (see
<xref target="RFC4898"/>), which tracks the number of bytes that are already
cumulatively acknowledged by the peer, can adopt this option.</t>
<t>A local variable <tt>ACK.MIN</tt> <bcp14>SHOULD</bcp14> be computed, which is used to
validate the <tt>SEG.ACK</tt>.</t>
<sourcecode>
if (tcpEStatsAppHCThruOctetsAcked &lt; MAX.SND.WND) {
    ACK.MIN = SND.UNA - tcpEStatsAppHCThruOctetsAcked;
} else {
    ACK.MIN = SND.UNA - MAX.SND.WND;
}
</sourcecode>
<t>Then the validation of <tt>SEG.ACK</tt> <bcp14>SHOULD</bcp14> be performed:</t>
<sourcecode>
if (SEG.ACK &lt; ACK.MIN) {
    send_challenge_ack;
    return;
}
</sourcecode>
<t>Though unlikely to happen, the 64-bit <tt>tcpEStatsAppHCThruOctetsAcked</tt> counter can overflow.
An implementation has to deal with <tt>tcpEStatsAppHCThruOctetsAcked</tt> overflows.</t>
</section>
</section>

<section>
<name>Security Considerations</name>
<t>This document defines ghost ACKs and provides two alternative mitigations
against ghost ACK based attacks.
The security considerations in <xref target="RFC5961"/> and
<xref target="RFC9293"/> still apply to implementations handling ghost ACKs as
described in this document.</t>
<t>TCP implementation supporting <xref target="RFC5961"/> might be subject
to side channel attacks based on challenge ACKs.
When the ghost ACK mitigations are implemented, such attacks might be used to
disclose the <tt>ISS</tt> as long as less than <tt>MAX.SND.WND</tt> bytes of
data have been cumulatively acknowledged or the fact that more than
<tt>MAX.SND.WND</tt> byte have been cumulatively acknowledged.</t>
</section>

<section>
<name>IANA Considerations</name>
<t>This document does not require any actions from IANA.</t>
</section>

  </middle>

  <back>
    <references>
      <name>References</name>
      <references>
        <name>Normative References</name>
        
        <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.0793.xml"/>
        <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.4898.xml"/>
        <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.5961.xml"/>
        <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.7323.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.9293.xml"/>

      </references>
 
      <references>
        <name>Informative References</name>             
          <reference anchor="SP2024Spoof" target="https://doi.ieeecomputersociety.org/10.1109/SP54263.2024.00182">
            <front>
              <title>TCP Spoofing: Reliable Payload Transmission Past the Spoofed TCP Handshake</title>
              <author initials="Y." surname="Pan" fullname="Y. Pan"></author>
              <author initials="C." surname="Rossow" fullname="C. Rossow"></author>
              <date year="2024" month="may"></date>
            </front>
            <seriesInfo name="DOI" value="10.1109/SP54263.2024.00182"></seriesInfo>
          </reference>
      </references>
    </references>
    
    <!-- <section>
      <name>Appendix 1</name>
      <t>This becomes an Appendix</t>
    </section> -->

    <section anchor="Acknowledgements" numbered="false">
      <!-- an Acknowledgements section is optional -->
      <name>Acknowledgements</name>
      <t>We thank Eric Dumazet for proposing the second mitigation option using <tt>tcpEStatsAppHCThruOctetsAcked</tt>.</t>
    </section>
    
    <!-- <section anchor="Contributors" numbered="false">
      
      <name>Contributors</name>
      <t>Thanks to all of the contributors.</t>
      <contact fullname="Jane Doe" initials="J" surname="Doe">
        
        <organization>Acme</organization>
        <address>
          <email>jdoe@example.com</email>
        </address>
      </contact>
    </section> -->
    
 </back>
</rfc>
