Forum Discussion

Brad_Baker's avatar
Apr 18, 2024

Chrome V 124+ on MacOS - Virtual Server Access Issue

(editors note: this is not just MacOS - appears to be all Chrome browsers regardless of OS) It appears that the latest version of Google Chrome (version 124) on  MacOS (ed. any OS) has broken the ...
  • candc's avatar
    candc
    Apr 22, 2024

    Brad_Baker  / LiefZimmerman  / Eric_Chen  / Stan_PIRON_F5 / Stanislas_Piro2 

    I have patched my copy of the original iRule with what I think is a working fix, but I would love if someone in the community could validate it, because my knowledge of the intricacies of the TLS packet is not strong.

    Essentially, I have replaced this if check in the original...

    # If valid TLS 1.X CLIENT_HELLO handshake packet
    if { [binary scan $payload cH4Scx3H4x32c tls_record_content_type tls_version tls_recordlen tls_handshake_action tls_handshake_version tls_handshake_sessidlen] == 6 && \
        ($tls_record_content_type == 22) && \
        ([string match {030[1-3]} $tls_version]) && \
        ($tls_handshake_action == 1) && \
        ($payloadlen == $tls_recordlen+5)} {

    ...with this block, which is intended to determine whether the reported TLS record length is longer than the payload we have and, if so, collect more packets until we have enough:

    # Keep collecting if CLIENT_HELLO messages that span more than one packet...
    if {![info exists payloadscan]} {
        set payloadscan [binary scan $payload cH4Scx3H4x32c tls_record_content_type tls_version tls_recordlen tls_handshake_action \
                                                            tls_handshake_version tls_handshake_sessidlen]
    }
    if {($payloadscan == 6)} {
        if {($tls_recordlen < 0 || $tls_recordlen > 16389)} {  # if we are asked to collect more than we will handle, bail...
            log local0.warn "[IP::remote_addr] : parsed TLS record length ${tls_recordlen} outside of handled length (0..16389)"
            reject
            return
        } elseif {($payloadlen < $tls_recordlen+5)} {          # if we have not collected enough yet, collect some more
            TCP::collect [expr {$tls_recordlen+5 - $payloadlen}]
            return
        }
    }
    
    # If valid TLS 1.X CLIENT_HELLO handshake packet
    if {($payloadscan == 6) && \
        ($tls_record_content_type == 22) && \
        ([string match {030[1-3]} $tls_version]) && \
        ($tls_handshake_action == 1) && \
        ($payloadlen == $tls_recordlen+5)} {

    This has allowed the rest of the original logic to capture the SNI server name and my services to resume operation.

    However, one new thing of note, is that the resulting values in $tls_handshake_preferred_version now include an extra value.  If I log this value, I can see...

    • Firefox returns 0304 0303 0302 0301
    • Chrome/Edge with --ssl-version-max=tls1.2 return 0303 only
    • Chrome/Edge v124 return xAxA 0304 0303

     

    The xAxA value changes every time -- so far, I have seen 1A1A, 7A7A, 8A8A, DADA and FAFA.  (I do not see a 7Fxy, as indicated in the switch statement).

    I am now wondering if this is just an implementation detail of the new Chrome TLS packet, or if I/we are now reading the preferred values from the wrong position in the payload.

    Is anyone able to verify the above?