re: Direct SSL connection and ALPN loose ends

  • Jump to comment-1
    Ranier Vilela<ranier.vf@gmail.com>
    Apr 29, 2024, 5:11 PM UTC
    Hi,
    With TLS 1.3 and others there is possibly a security flaw using ALPN [1].
    It seems to me that the ALPN protocol can be bypassed if the client does
    not correctly inform the ClientHello header.
    So, the suggestion is to check the ClientHello header in the server and
    terminate the TLS handshake early.
    Patch attached.
    best regards,
    Ranier Vilela
    [1] terminate-tlsv1-3-handshake-if-alpn-is-missing
    https://stackoverflow.com/questions/77271498/terminate-tlsv1-3-handshake-if-alpn-is-missing
    • Jump to comment-1
      Heikki Linnakangas<hlinnaka@iki.fi>
      Apr 29, 2024, 5:56 PM UTC
      On 29/04/2024 20:10, Ranier Vilela wrote:
      Hi,
      With TLS 1.3 and others there is possibly a security flaw using ALPN [1].
      It seems to me that the ALPN protocol can be bypassed if the client does > not correctly inform the ClientHello header.
      So, the suggestion is to check the ClientHello header in the server and
      terminate the TLS handshake early.
      Sounds to me like it's working as designed. ALPN in general is optional; if the client doesn't request it, then you proceed without it. We do require ALPN for direct SSL connections though. We can, because direct SSL connections is a new feature in Postgres. But we cannot require it for the connections negotiated with SSLRequest, or we break compatibility with old clients that don't use ALPN.
      There is a check in direct SSL mode that ALPN was used (ProcessSSLStartup in backend_startup.c):
      if (!port->alpn_used)
      {
      ereport(COMMERROR,
      (errcode(ERRCODEPROTOCOLVIOLATION),
      errmsg("received direct SSL connection request without ALPN protocol negotiation extension")));
      goto reject;
      }
      That happens immediately after the SSL connection has been established.
      Hmm. I guess it would be better to abort the connection earlier, without completing the TLS handshake. Otherwise the client might send the first message in wrong protocol to the PostgreSQL server. That's not a security issue for the PostgreSQL server: the server disconnects without reading the message. And I don't see any way for an ALPACA attack when the server ignores the client's message. Nevertheless, from the point of view of keeping the attack surface as small as possible, aborting earlier seems better.
      --
      Heikki Linnakangas
      Neon (https://neon.tech)
      • Jump to comment-1
        Ranier Vilela<ranier.vf@gmail.com>
        Apr 29, 2024, 6:07 PM UTC
        Em seg., 29 de abr. de 2024 às 14:56, Heikki Linnakangas <hlinnaka@iki.fi>
        escreveu:
        On 29/04/2024 20:10, Ranier Vilela wrote:
        Hi,

        With TLS 1.3 and others there is possibly a security flaw using ALPN [1].

        It seems to me that the ALPN protocol can be bypassed if the client does
        not correctly inform the ClientHello header.

        So, the suggestion is to check the ClientHello header in the server and
        terminate the TLS handshake early.

        Sounds to me like it's working as designed. ALPN in general is optional;
        if the client doesn't request it, then you proceed without it. We do
        require ALPN for direct SSL connections though. We can, because direct
        SSL connections is a new feature in Postgres. But we cannot require it
        for the connections negotiated with SSLRequest, or we break
        compatibility with old clients that don't use ALPN.
        Ok.
        But what if I have a server configured for TLS 1.3 and that requires ALPN
        to allow access?
        What about a client configured without ALPN requiring connection?

        There is a check in direct SSL mode that ALPN was used
        (ProcessSSLStartup in backend_startup.c):
        if (!port->alpn_used)
        {
        ereport(COMMERROR,
        (errcode(ERRCODEPROTOCOLVIOLATION),
        errmsg("received direct SSL connection
        request without ALPN protocol negotiation extension")));
        goto reject;
        }

        That happens immediately after the SSL connection has been established.

        Hmm. I guess it would be better to abort the connection earlier, without
        completing the TLS handshake. Otherwise the client might send the first
        message in wrong protocol to the PostgreSQL server. That's not a
        security issue for the PostgreSQL server: the server disconnects without
        reading the message. And I don't see any way for an ALPACA attack when
        the server ignores the client's message. Nevertheless, from the point of
        view of keeping the attack surface as small as possible, aborting
        earlier seems better.
        So the ClientHello callback is the correct way to determine the end.
        best regards,
        Ranier Vilela
        • Jump to comment-1
          Heikki Linnakangas<hlinnaka@iki.fi>
          Apr 29, 2024, 6:36 PM UTC
          On 29/04/2024 21:06, Ranier Vilela wrote:
          Em seg., 29 de abr. de 2024 às 14:56, Heikki Linnakangas > <hlinnaka@iki.fi <mailto:hlinnaka@iki.fi>> escreveu:
          On 29/04/2024 20:10, Ranier Vilela wrote:
          Hi,

          With TLS 1.3 and others there is possibly a security flaw using
          ALPN [1].

          It seems to me that the ALPN protocol can be bypassed if the
          client does
          not correctly inform the ClientHello header.

          So, the suggestion is to check the ClientHello header in the
          server and
          terminate the TLS handshake early.
          Sounds to me like it's working as designed. ALPN in general is
          optional;
          if the client doesn't request it, then you proceed without it. We do
          require ALPN for direct SSL connections though. We can, because direct
          SSL connections is a new feature in Postgres. But we cannot require it
          for the connections negotiated with SSLRequest, or we break
          compatibility with old clients that don't use ALPN.
          Ok.
          But what if I have a server configured for TLS 1.3 and that requires > ALPN to allow access?
          What about a client configured without ALPN requiring connection?
          Sorry, I don't understand the questions. What about them?
          --
          Heikki Linnakangas
          Neon (https://neon.tech)
          • Jump to comment-1
            Ranier Vilela<ranier.vf@gmail.com>
            Apr 29, 2024, 7:19 PM UTC
            Em seg., 29 de abr. de 2024 às 15:36, Heikki Linnakangas <hlinnaka@iki.fi>
            escreveu:
            On 29/04/2024 21:06, Ranier Vilela wrote:
            Em seg., 29 de abr. de 2024 às 14:56, Heikki Linnakangas
            <hlinnaka@iki.fi <mailto:hlinnaka@iki.fi>> escreveu:

            On 29/04/2024 20:10, Ranier Vilela wrote:
            Hi,

            With TLS 1.3 and others there is possibly a security flaw using
            ALPN [1].

            It seems to me that the ALPN protocol can be bypassed if the
            client does
            not correctly inform the ClientHello header.

            So, the suggestion is to check the ClientHello header in the
            server and
            terminate the TLS handshake early.

            Sounds to me like it's working as designed. ALPN in general is
            optional;
            if the client doesn't request it, then you proceed without it. We do
            require ALPN for direct SSL connections though. We can, because
            direct
            SSL connections is a new feature in Postgres. But we cannot require
            it
            for the connections negotiated with SSLRequest, or we break
            compatibility with old clients that don't use ALPN.

            Ok.
            But what if I have a server configured for TLS 1.3 and that requires
            ALPN to allow access?
            What about a client configured without ALPN requiring connection?

            Sorry, I don't understand the questions. What about them?
            Sorry, I'll try to be clearer.
            The way it is designed, can we impose TLS 1.3 and ALPN to allow access to a
            public server?
            And if on the other side we have a client, configured without ALPN,
            when requesting access, the server will refuse?
            best regards,
            Ranier Vilela