How Mishandling of WebSockets Can Cause DoS and Energy Theft

Picture of Doron Porat
Doron Porat

Software Engineer at Saiflow

Editor’s note: Read our summary blog post for a brief explanation of the vulnerability and its potential impact.


The SaiFlow Research Team recently discovered a flaw in the implementations of management systems for Smart EV charger points (Charging Stations Management Systems – CSMS) allowing attackers to cause Denial of Services (DoS) and perform energy theft. The vulnerability relies on how those systems mishandle multiple connections of a smart Electric Vehicle (EV) charge point to the CSMS platform. This vulnerability, which exists in the WebSockets for OCPP 1.6 protocol, can be used by an attacker to hijack the connection between the CSMS and the charge point for the sake of disabling the charger and entire station, spoofing drivers’ identity, causing billing discrepancies, and stealing energy.

In some cases, the attacker might receive requests containing sensitive information like credentials for file servers used for over-the-air updates and uploading log files. These credentials might be used by attackers to further their attack process.

This SaiFlow Research Team blog covers the basic terms of the Smart EV charging industry, impact showcases when using different configurations for charge points, a technical overview of a CSMS source code, and recommendations for enhancing the cybersecurity posture and resiliency.


Unlike traditional gas stations, EV charging infrastructure was built with modern remote management abilities and interconnectivity in mind. In the EV charging industry, there are main three players:

  • The EV Charge Point Operator
    Also referred to as CPO, is in charge of managing the chargers including setting policies, prices, issuing drivers’ identities, etc.
  • The charging management software providers
    Most EV chargers today used in multi-family workspaces and public parking slots are remotely managed by a CSMS (Charging Station Management System). CSMS is a critical part of keeping track of infrastructure stability, energy management, authorization of electric vehicle (EV) charge requests, and billing reports.
  • The EV charge point vendors
Red electric vehicle charging with a red EV charger

The de-facto protocol used to manage the charge points and their connections with the CSMS is the OCPP (Open Charge Point Protocol). The OCPP is an open standard protocol and is mostly used for communication between chargers and CSMS providers. The protocol uses HTTP(S) and WebSockets. It defines charge point authentication methods, message structure such as SOAP or JSON, and the type of OCPP operations that each version should support such as over-the-air updates, divers’ authorization, and configuration management. Today the most common version of the protocol is the OCPP1.6J which uses WebSockets with messages structured in JSON.

OCPP grid layout

In the OCPP standard, every charger has a unique identifier that is used by the charger to identify itself to the CSMS provider for provisioning. When a charger creates an OCPP connection to the CSMS, using WebSocket channels, it provides its identifier by setting a parameter in the URL. For example, assuming a CSMS server is at ws:// and the charge point’s unique identifier is “CP3211”, the resulting URL of the request will be ws://

OCPP CSMS layout

Before the energy can transfer from the charge point to the EV, the driver has to authenticate itself to the charge point or to the CSMS. Usually, the authentication is performed using an RFID tag or a mobile app. The energy transfer period is called a Transaction in the OCPP standard.

The driver identity is represented as idTag in the OCPP standard, and it’s used by the CSMS to correlate the charging operation with the billing account. Before the owner of an EV starts the charging transaction, the charger needs to validate the given idTag and authorize the operation. The authorization approval is done remotely by the CSMS or locally based on the Local Authorization List and the Authorization Cache (we’ll cover this subject later in this blog).

“The lack of a clear guideline for multiple active connections can be exploited by attackers to disrupt and hijack the connection between the charge point and the CSMS.”

Uncovering The Problem

According to the OCPP protocol standard with its security extensions of version 1.6J, it supports three authentication methods for the charge points to authenticate to the CSMS:

  1. Charger identity alone
  2. Charger identity, and credentials (basic authentication)
  3. Charger identity and client certificate.

Using method #1 might allows cyber attackers to spoof a connection from a valid charger and act on its behalf.

The OCPP standard doesn’t define how a CSMS should accept new connections from a charge point when there is already an active connection. The lack of a clear guideline for multiple active connections can be exploited by attackers to disrupt and hijack the connection between the charge point and the CSMS.

The OCPP vulnerability described above enables a new attack method that allows an attacker to disrupt the services of chargers by creating an additional WebSocket connection to their CSMS provider while using the same identity of the charger that is already connected. When the charge point is disconnected or is in an offline state, there are multiple abuse scenarios that an attacker might exploit. Saiflow’s Research team, which discovered the attack method, tested the attack with multiple known CSMS providers and discovered that they are vulnerable to this attack. It’s important to note that each CSMS provider handles differently the situation of multiple connections from the same charge point identifier.

What is the problem with my charger being offline?

Charge points rely on their connection to the CSMS to support and audit charging operations. If a charge point isn’t able to authorize the driver’s identity, the charging transaction may not be accepted and the EV won’t be charged. When the charger is offline there are two main consequences: 1) Drivers won’t be able to charge thus causing a DoS. 2) If the charge point allows charging for unregistered idTags then cyber attackers could be able to steal energy. Depending on the charge point configuration, DoS and/or energy theft might be executed.

The OCPP and the charge point use four variables to decide whether or not to approve an energy transaction and allow a driver to charge.

Graph showing the decision process of an offline charger

Local Authorization List is a list of records when each record includes the idTag (driver identity), authorization status, and expiration date. The authorization status must be one of these four values: Valid, Expired, Blocked, or Blacklisted. Only the Valid status means that the idTag is authorized to start a charging transaction and the rest means that the transaction will be rejected. The Local Authorization List can be synchronized with the CSMS to store locally a list of drivers’ identifiers (but it’s not obligated).

Authorization Cache if implemented, the Authorization Cache will maintain a list of records containing idTags that were previously authorized successfully by the CSMS.

LocalAuthorizeOffline is the configuration key that defines whether the charger will start transactions when it is offline (disconnected from the CSMS). When this key is enabled, the authorization process of a new transaction request will happen locally by validating the given idTag with the Local Authorization List and/or Authorization Cache. If this field is set to False, then the charger will not operate offline causing a DoS.

AllowOfflineTxForUnknownId is the configuration key that defines whether the charge point will automatically authorize transactions from any idTag as long as the idTag is not explicitly blocked by the Local Authorization List when the charger is offline.

Now that we have covered the features and configuration keys of charge points, we will describe how their settings might affect the attack methods the charge point is exposed to.

  1. If LocalAuthorizeOffline is set to False (disabled),the charge point will not start a new charging transaction while the charge point is offline. This will render the charger as not operational for new charging requests and cause a DoS.
  2. If LocalAuthorizeOffline isset to True (enabled):
    1. And AllowOfflineTxForUnknownId is True (enabled), the charge point will approve new transactions by unregistered CSMS drivers. Attackers might exploit it for energy theft by disrupting the charger connection so that it will become offline. During that time, the charger will approve the transaction of an unknown idTag and allow charging without any payment or a billing account that can be correlated to it later.
    2. And AllowOfflineTxForUnknownId is False (disabled), the charge point will not approve transactions of unknown identifiers and cause a DoS if a valid driver’s idTag isn’t explicitly stored in the Local Authorization List and/or Authorization Cache. In a case where there is no CPO policy defining regular synchronization of the allowed idTags between the CSMS and the charger, disabling this key can result in DoS for legitimate idTags that were not sent to the charger in advance.
      Note: By saying the above, we don’t suggest implementing a sync policy for idTags using the Local Authorization List. We acknowledge this functionally and share the use case with which this feature was aimed to assist with.
Smart city cybersecurity separator

OCPP Hijack Use Cases

As mentioned above, cyber attackers can hijack the CSMS charge point connection due to the mishandling of multiple WebSocket connections. When a CSMS creates a new connection for an already connected charge point, one of the following approaches will be used:

“The attacker can be exposed to sensitive information sent by CSMS like requests to upload log files that contain credentials to file servers, idTags sent as part of Local Authorization List …”

1. Closing the original connection

Some CSMS providers close the original charger connection when a new connection with the same identifier is established, resulting with the original charge point being offline. In this case, the charge point will realize it was disconnected and try to reconnect to the CSMS after a short period of time. An attacker with intentions of disrupting a charger can create a tool that establishes a new connection to the CSMS provider every short period of time in order to continuously disconnect the original charger and resulting in a constant offline state of the target charger.

As explained in the section above, an offline charge point can cause a DoS for legitimate drivers. During this short period of time, the attacker can act on behalf of the charge point and start charging transactions causing billing discrepancies.

GIF of a 2 computer terminals demonstrating a charge point connection on the right terminal, and attacker shell on the left terminal

On the right side, we simulate the original charge point connection. On the left side, we simulate the attacker.

2. Keeping both connections alive but not responding over the original WebSocket connection

In this case, the CSMS keeps both connections open but doesn’t communicate and doesn’t respond to requests sent from the original WebSocket connection.

In this scenario, the charge point will not go into an offline state and won’t try to initiate a new connection for a long period of time. During that time, the attacker could have better opportunities to receive sensitive data from the CSMS.

GIF of a 2 computer terminals demonstrating a charge point connection on the right terminal, and attacker shell on the left terminal.

This scenario shows the attacker receiving WebSocket response after the session was hijacked, while the legitimate charger receives status 1006 (Unexpected EOF).

Keeping both connections alive and returning responses of requests from the original WebSocket to the second WebSocket connection

The SaiFlow Research team found that on some occasions CSMS providers keep both connections open but send the responses only to the second connection. This may result in information sent from the original charge point being fully or partially included in the response message exposed to the attacker. Also, it might result in unanswered requests from the original WebSocket. If this happens, there is a critical security issue that exposes sensitive data originating from the charge point itself. For example, when a StartTransaction request is being sent to the CSMS, the response of it might include its parent idTag as part of the IdTagInfo object. Although this is an optional field, it is one of the potential methods for an attacker to compromise drivers’ identity.

LocalPreAuthorize configuration key defines whether a charge point will use Authorization Cache and/or Local Authorization List as part of the authorization process when initiating a charging transaction without waiting for confirmation from the CSMS. If this key is set to False, then the charge point must wait for the CSMS authorization response before it can start a charging operation. Since the charge point is not in an offline state and not receiving responses from the CSMS, the charge point will be stuck waiting for the CSMS authorization response, causing a DoS.

GIF of a 2 computer terminals demonstrating a charge point connection on the right terminal, and attacker shell on the left terminal.

This scenario shows the attacker receiving WebSocket response after the session was hijacked. If the legitimate charger sends requests to the CSMS the attacker receives the responses that should have been sent to the charger.

3. Keeping both connections alive and returning responses to the requesting WebSocket connection

Other CSMS providers keep both WebSockets alive, accepting requests from both WebSocket connections and responding to the WebSocket that sent the request. Keeping both connections alive allows the charge point to keep its functionality and avoids accidentally closing the original charge point in favor of the attacker’s connection. This is the optimal way we found to make sure the charge points won’t get into an offline state. However, the way a CSMS provider manages requests initiated by it and sent to a charge point is handled differently by different CSMS providers. The SaiFlow Research team found that some CSMS providers who initiate the request to a charge point are sending the messages only to the last established connection. This can result in the partial disruption of charge points. The charge points won’t receive update operations from the CSMS like configuration changes, firmware updates, charging profiles, etc.

In addition to the disruption, the attacker can be exposed to sensitive information sent by CSMS like requests to upload log files that contain credentials to file servers, idTags sent as part of Local Authorization List synchronization and idTags that are included in RemoteStartTransaction messages. The attacker can abuse that information to conduct energy theft by impersonating a driver using the stolen idTag, selling a list of idTags and credentials over the dark web to threat actors, and more.

GIF of a 2 computer terminals demonstrating a charge point connection on the right terminal, and attacker shell on the left terminal.

This scenario shows the attacker receiving WebSocket response after the session was hijacked, while the charger connection is kept alive; and both function as the charger at the simultaneously.

Example attack on CSMS

One of the known CSMS providers that exist in the open source community is Steve, which manages both connections but sends CSMS requests to the last connection established from the charger (above case no. 3). After analyzing Steve’s source code, the following is the class that manages the WebSocket connections:
Note, what we refer to as a connection in this blog post, Steve refers to as a ‘session’.

SteVe open source code snippet. Inside the method onOpen we can see that SteVe doesn't check if the charger is already active.

As we can see in line 24: sessionContextStore.add(chargeBoxId, session, pingSchedule);, Steve does not check if the charge point id already has a connection, before storing the new session alongside the existing one.

The operation on connectedCallbackList intends to send internal system notification in case a new connection is established and no connection from that charge point was established before that. This doesn’t have an effect on our attack implementation.

SteVe open source code snippet showing SteVe manages the chargers using a HashMap.

Steve manages each charge point in a HashMap which contains an array of sessions for each charge point. If a session already exists, it will add an additional session to that array.

SteVe open source code snippet showing the code that was used to demonstrate the attack

Following our analysis, in the code snippet above we examine the GetConfiguration operation of OCPP1.6 as an example of an operation that a CSMS initiates. Since the protocol version that we use is WebSockets with JSON, Steve will call the runPipeline function.

SteVe open source code snippet showing how SteVe gets the session for the communication context with the charger

Inside the runPipeline function, there is a call to run function. Steve prepares the message and then executes line 34: endpoint.getSession(chargeBoxId).

SteVe open source code snippet showing the getSession method that was mentioned in the previous image
SteVe open source code snippet showing the getSession strategies implemented to get the session.

The getSession returns the session of that charge’s identifier but as mentioned earlier, when a new connection is created, Steve adds the last session to the charge point’s array of sessions. The default configuration is set to ALWAYS_LAST as described in the code snippet above. Steve will get the last session from the array and send its GetConfiguration request through it.

However, Steve allows setting a ROUND_ROBIN approach to handling multiple sessions from the same charger.

This emphasizes the fact that CSMS providers can implement different approaches to handling multiple connections from the same charge point. As mentioned, not having a standard approach to handling multiple connections provides opportunities for attackers to exploit this architecture.

Recommendation for mitigation

How CSMS providers can mitigate this attack?

  1. Since charger points commonly rely on SIM cards to communicate over the internet with the CSMS, creating an allow-list to allow connections only from a specific IP address will not work and can cause disruption to legitimate communication attempts. However, limiting the allowed IP addresses to a specific region/provider will limit the attacker and make it much harder to access the CSMS on behalf of the CPO charge points.
  2. When a CSMS has more than one connection from a single charge point, both connections should be managed by the CSMS until it determines the legitimate connection by actively sending a WebSocket ping or triggering an OCPP Heartbeat request. If one of the connections is not responsive, the CSMS should eliminate that connection. If both of the connections are responsive, the CSMS should allow site operators to control which of the multiple connections they decide to close. All of that while managing and logging the two chargers’ operations separately, for example – calculating the energy consumption.

Looking into the future, OCPP 2.0.1, and its security extension, will require credentials as the minimal obligatory security profile which might make the above recommendation a redundant one. However, OCPP 2.0.1 is new and still only in the early stages of adoption. We will follow closely for new developments and validate the exposure of these vulnerabilities.

How CPOs can mitigate this attack?

  1. Monitor anomalies of charge points and the use of energy consumption.
  2. Monitor multiple connections using the same charge point identity if the logs of the CSMS provides such events.
  3. Add basic authentication mechanism to your charge points. The owner or operator of the charge points should set a stronger security profile to require basic authentication or preferably mutual TLS authentication. If using basic authentication, it should involve creating a customized password for each charge point and avoiding the use of the default password provided by the charge points’ manufacturers. By enforcing this policy, it will be harder for attackers to spoof the charger’s identity which will also make the multiple charger connections attack method obsolete.

About SaiFlow

SaiFlow provides a tailor-made cybersecurity solution for CP, EVSE, DER, energy networks and assets, focusing on securing their standard protocols, such as OCPP, OCPI, IEEE 2030.5, DNP3, IEC 61850, and more. SaiFlow’s platform provides posture management, cyber monitoring, detection, and prevention abilities, all incorporating smart-grid and sensor data in establishing the baselines, correlations, and anomalies of these types of networks.

Skip to content