Skip to navigation Skip to main content Skip to footer

EAP-TLS: The most secure option?

By Apostolos Gioulis

09 April 2025

EAP-TLS: The most secure option?

Introduction

We are often called to assess the security of the Wireless networks of our customers. The recommendation for most issues affecting wireless tends to include the deployment of EAP-TLS, instead of insecure protocol X. EAP-TLS can be considered the gold standard of wireless security as it uses public key certificates for authentication and does not rely on secrets or user controlled passwords.

In this blog post, we explore how truthful the gold-standard claim can be, what can go wrong with our EAP-TLS deployment and how can we avoid it. But most of all, it is a great opportunity for me to lament the warning shown by MS Windows when the user connects to an potential evil-twin; but more to follow.

If you are familiar with how EAP-TLS works I would urge you to skip to the two main security issues that can arise with EAP-TLS (Username enumeration and Server Validation Misconfigurations). If you are more interested in the lamentation go here.

Terminology

The following terms will be used so might as well provide some rough definitions:
  • Supplicant: Fancy word for client, i.e. software component that handles the WiFi connection, e.g. wpa_supplicant on Linux
  • Authenticator: The switch, most likely. Confusingly the authenticator wont be doing any actual authentication it will just relay messages from the client to the authentication server
  • Authentication Server: The server actually responsible for authentication, most likely a RADIUS server.

EAP-TLS - The theory

A brief introduction

Extensible Authentication Protocol (EAP) is a flexible authentication framework widely used in network security, especially in WPA2-Enterprise Wi-Fi environments. Rather than being a specific authentication method, EAP acts as a container for multiple authentication protocols, allowing networks to verify user credentials through different mechanisms such as passwords, certificates, or token-based authentication.

EAP-TLS (Extensible Authentication Protocol - Transport Layer Security) is one of the authentication methods used in EAP. Unlike password-based protocols like MS-CHAP or PEAP, EAP-TLS relies on digital certificates for both the client and the authentication server, eliminating the risk of credential theft through brute force or phishing attacks.

Handshake Overview

Having introduced what EAP-TLS is, let's dive into how the actual handshake and the establishment of the channel work. When establishing a channel, we can think of it in two layers: the EAP layer and the TLS layer.

Roughly how it works is that first, EAP sends a few initial messages to set up the authentication process. This is where the client and server agree on the authentication method (EAP-TLS in this case). Once that's done, TLS takes over to handle the actual authentication.

A more visual overview of the handshake, subsequently described, can be seen bellow, taken from the RFC (in hindsight I should have just made a graphical diagram as it arguably took me more time to get the spacing right, but there you go..):

                                                        <- EAP-Request/Identity
 EAP-Response/Identity (MyID) ->
                                                        <- EAP-Request/EAP-Type=EAP-TLS (TLS Start)
 EAP-Response/EAP-Type=EAP-TLS (TLS client_hello)->
                                                        <- EAP-Request/EAP-Type=EAP-TLS (TLS server_hello,
                                                            TLS certificate, [TLS server_key_exchange,] 
                                                            TLS certificate_request, TLS server_hello_done)
 EAP-Response/EAP-Type=EAP-TLS 
 (TLS certificate (no cert), 
 TLS client_key_exchange, 
 TLS change_cipher_spec, TLS finished) ->
                                                        <- EAP-Request/EAP-Type=EAP-TLS
                                                            (TLS change_cipher_spec,finished,hello_request)
 EAP-Response/EAP-Type=EAP-TLS (TLS client_hello)->
                                                        <- EAP-Request/EAP-Type=EAP-TLS
                                                            (TLS server_hello,TLS certificate,
                                                            TLS server_key_exchange,TLS certificate_request,
                                                            TLS server_hello_done)
            

 

Lets go through the main parts of EAP-TLS handshake; briefly, cause I want to go to the interesting part:

  1. Share certificate with the client: Required to authenticate to the server (not part of the protocol but kind of a prerequisite). This, I imagine, was cumbersome at one point but nowadays with modern MDM is as easy as configuring a device profile. The example image shows the relevant page in Intune:
  2. EAP - EAPoL Start: FROM: Supplicant - TO: Authentication Server - "Hello authenticator, I hear you speak EAP, I want to connect.."
  3. EAP - Identity Request: FROM: Authentication Server - TO: Supplicant - "Who are you, you supplicant.."? This can be useful if you have multiple authentication methods depending on the client. Not actual authentication.
  4. EAP - Identity Response: FROM: Supplicant - TO: Authentication Server - "I am X, Y X". Based on the response, the EAP server will determine what authentication method it will use for that specific client. Here a username enumeration issue can arise.
  5. Mutual(?)TLS Authentication: Having identified the user, EAP knows that they need to be authenticated using mTLS. So mTLS starts. mTLS stands for mutual TLS where both the client validates the identity of the server and the server validates the identity of the client. I wont go much more into the specifics of TLS here but my advice, if you are a young security person, is highly recommended you learn very well how TLS works (it comes up in conversation a lot). Here the second issue can arise, as described in m(?)TLS.

Having somewhat understood how EAP-TLS' works lets look at the two main security issues that can arise

EAP - Username Enumeration

As discussed above, the EAP server will request the identity of the client to enable it to make the decision what authentication method to use. If that identity is the username of the domain user, I believe this is the default behaviour, this results in an unauthenticated username harvesting avenue. All a threat actor needs to do is find a comfortable bench in the vicinity of the victims office, connect their laptop to an strong antenna (I would keep the antenna in my bag to avoid the confused stares of passersby), and they can start collecting usernames.

This can be easily done with well-known tools. For example:

 airodump-ng -i $IFACE -c $CHAN --bssid $BSSID
 tshark -i "$IFACE" -Y eap -V |grep "Identity: *[a-z]\|*[A-Z]\|*[0-9]" # Connect with your phone to wifi to test

Fix

EAP-TLS peer and server implementations MAY support privacy. Disclosure of the username is avoided by utilizing a privacy Network Access Identifier (NAI)RFC4282 in the EAP-Response/Identity, and transmitting the peer certificate within a TLS session providing confidentiality.

MAY is the key word here as on the MS Windows EAP-TLS client doesn't support. In the screenshot below observe the difference between the relevant settings of PEAP and EAP-TLS. One supports privacy, the other one doesn't.

In the absence of this feature we could configure EAP to use "Computer Authentication" instead of "User authentication". As a result, instead of sending the username, the computer name will be sent in the EAP-Response/Identity packet. This will cause the supplicant to respond with the name of the computer, instead of the username of the logged-in user. Computer names are not that interesting so risk mitigated, the threat actor can enjoy the british weather on the bench with our blessings. The relevant option on Windows can be seen below:

EAP - m(?)TLS

The more observant reader will have spotted by now the ingenious use of the question mark (?) on top of the leter "m" of mTLS. This is because the supplicant can be configured not to validate the certificate of the server or to allow the user to accept untrusted certificates. As such, the server validates indeed the client, but the client does not necessarily validate the server, so no "m" for you.

On MS Windows this can be configured in the network configuration dialog. These configurations that can also be configured in the WiFi profile to be pushed on the devices via Group Policy (microsoft insecure example). We will use the GUI here to make it more appealing to the masses. The relevant configuration options can be seen in the screenshot:

So lets review the relevant options:

  • Verify the server's identity by validating the certificate:
    • (checked) Our client will validate the certificate and ensure it was issued by a trusted CA.
    • (unchecked) Our client will accept any ol' certificate including self signed. This is the most insecure option and should always be confirmed to be checked!
  • Connect to these servers: If the certificate's CN or SAN does not match any of the specified server names, authentication fails. If left empty, Windows will accept any valid certificate from a trusted CA without verifying the server name.
  • Don't prompt user to authorise new servers or trusted certification authorities: This is the most common misconfiguration.
    • (checked) The user cannot accept untrusted certificates. Such connection attempts will fail.
    • (unchecked) Windows will prompt the user with a warning about the untrusted certificate. They will see a message informing them that the certificate is not trusted (because it's self-signed or from an untrusted CA), and they will be asked if them want to trust the certificate and proceed with the connection.

 

Having understood how misconfigurations can arise in EAP-TLS deployments, as far as server verification goes, lets try to see how the various configuration combinations fare against evil-twin attacks.

Evil Twin Attack Scenarios

Evil Twin attacks refer to a rogue access point that mimics a legitimate network (same SSID), tricking clients into connecting to it. Below we will review how a potential victim fares against such an attack for EAP-TLS. The threat actor will be using the same modified version of hostapd that skips client certificate validation (I wish I could brag that I came up with this but when I started working on a similar solution I found, to my dismay, that someone had already done it in a much better way). The modified hostapd is described in the excellent referenced article src

In each scenario the client connects to an EAP-TLS access point with the same name as their corporate one (evil twin,) that has been configured with a self signed certificate or a certificated that was not issued by a trusted signing authority.

Scenario 1: Client validates server's identity and user is not prompted to trust certificates

Client attempts to connect to the evil twin. Since the certificate is not trusted, the client will reject it and a relevant event will be created on the system. Below, observe the packet capture of the failed TLS handshake and the event created by Windows, alerting the blue team that a potential evil-twin attack is taking place:

Scenario 2: Client validates server's identity and user can be prompted to trust certificates

Client attempts to connect to the evil twin. The user is then prompted to accept the certificate. if accepted, the client will succesfully connect to the evil twin and the attacker will have achieved their goal. Now, lets have a look at the warning the user is presented with to decide whether they should connect to the network or not:

Lets me reiterate the presented message:

"If you expect to find X_SSID in this location, go ahead and connect. Otherwise, it may be a different network with the same name"
This by no means conveys the severity of the scenario and the threat the user is under. One would expect big yellow warning signs, exclamation points, red, danger, caution. But instead all the user gets is an underwhelming message that urges them to connect to the network as long as the location where they reached it is the expected one.

To drive the point home more, lets see the decision process of a user connecting to the evil twin network. In the diagram below a user is called to decide whether to connect to an evil twin, solely on what the message urges them to do and on how that message is presented:

As we can deduce, a reasonable user will connect to the evil-twin more often than not.

Lets contrast this to a warning we get when visiting a website with a self-signed certificate, which is a similar situation. 

Now that is more like it! The user can see that this looks serious the message, "I should tread with caution" is clearly conveyed. There is a clear warning that the confidentiality of our data is at stake. Not only that, but the user needs to do extra work to accept the untrusted certificate, click on Advanced and then accept responsibility for the grave mistake they made.

I reported this situation to Microsoft as a security vulnerability (VULN-132369) but it was not accepted, given that no trust boundaries are being crossed. Even though I see the point, I respectfully disagree. Even though message in itself does not cross a trust boundary (how could it, it's just a message), it does enable and dare I say urge the user to cross very important trust boundaries by connecting to an untrusted network without being informed to understand what they are doing. I would urge Microsoft to reconsider and treat this with the importance it deserves.

Scenario 3: Client does not validate the server's identity

Client connects to the evil twin. Not much to say here. The user will have no accessible way of known whether they connected to the legitimate network or an evil twin. The client will accept any ol' certificate. This is the worst of the 3 by far and should be avoided at all costs.

Fix

When setting up EAP-TLS make sure to always validate the server certificate and do not allow your users to accept untrusted certificates. You could also specify the fingerprint of trusted CAs to be accepted, further limiting any exportability. This can be done by setting the relevant options in the UI on the client or in the Group Policy network profile. The specification for the profile can be can be found in Microsoft documentation (section 2.2.3.2.8 ServerValidationParameters). For example the following section enforces server validation, accepts only specific CA's and does not allow the user to accept untrusted certificates:
 <ServerValidationParameters>
    <!-- DisableUserPromptForServerValidation ensures that certificate errors cause immediate connection refusal -->
    <DisableUserPromptForServerValidation>true</DisableUserPromptForServerValidation>

    <!-- PerformServerValidation is enabled to ensure server -->
    <!-- certificate is validated during authentication -->
    <PerformServerValidation>true</PerformServerValidation>

    <!-- ServerNames lists the allowed servers, preventing clients from connecting to unauthorized servers -->
    <ServerNames>
        <ServerName>server.example.com</ServerName>
        <ServerName>secure-portal.example.com</ServerName>
    </ServerNames>

    <!-- AcceptServerName enforces validation against the -->
    <!--server name to ensure it matches the expected names -->
    <AcceptServerName>true</AcceptServerName>

    <!-- TrustedRootCA specifies the trusted root certificate authorities; -->
    <!--only certificates issued by these CAs will be accepted -->
    <TrustedRootCA>
        <Thumbprint>ABCDEF1234567890ABCDEF1234567890ABCDEF12</Thumbprint> <!-- Example Thumbprint -->
        <Thumbprint>0987654321FEDCBA0987654321FEDCBA09876543</Thumbprint> <!-- Another Trusted Root Thumbprint -->
    </TrustedRootCA>
 </ServerValidationParameters>;

Conclusion

EAP-TLS can indeed be a very secure way to authenticate to networks. As with everything, however, how we configure it matters. Security makes or breaks with how we do things and this is a wonderful case where extra security can be deployed seamlessly (in most cases) without causing much kerfuffle for our users.

The final message I want to leave you with is that it is our duty, as an industry, to appropriately inform our users for any security risks they might be facing. The choice can be theirs to make, but we have a duty to inform them, clearly and appropriately, on what that choice is.