= VORACLE attack and OpenVPN = == Background == Security researcher Ahamed Nafeez has [https://speakerdeck.com/skepticfx/voracle-compression-oracle-attacks-on-vpn-tunnels presented a new attack vector] which targets VPN tunnels which utilizes compression, named **VORACLE**. The attack vector bears similarities to the CRIME and BREACH attacks, which hit especially HTTPS based connections. The crux of this attack is the compression feature OpenVPN has had support for since the early OpenVPN v1.x days, in various ways. The compression feature is being enabled when you use one of the following configuration options: * `--comp-lzo` * `--comp-lzo yes` * `--comp-lzo adaptive` * `--compress lzo` * `--compress lz4` * `--compress lz4-v2` Configurations *NOT* using `--comp-lzo` or `--compress` are *NOT* affected by VORACLE. === Simplified Example === The example mentioned here is not the only possible attack against encryption + compression. It is also very simplified to explain the principle of attacks like VORACLE, CRIME and BEAST. Alice has setup a login page. To check passwords entered there, Alice sends a message like "tell me if matches " to Bob. The more similar the is to the better this message compresses. If the attacker Eve can ask Alice to verify passwords and can see the length of the encrypted message, she gets a pretty good idea how close her guesses are as the encrypted message gets shorter when her guesses get better. Without compression the length of the encrypted packets does not change, so Eve cannot gain any information. (Strictly speaking the length changes if Eve's password length changes but that gives no additional information) The real world attacks are more complicated and need to take into account the specific circumstances (e.g. HTTPS or VPN) but they rely on the same principle as demonstrated in this simple example. === Compression is **NOT** enabled by default === It is important to know that compression has never been enabled by default. An OpenVPN configuration (implying both the local and remote side) must explicitly enable compression. The options here cover what is called the OpenVPN Data Channel in the wire protocol. The data channel is used to transfer network traffic from one side to the other side. OpenVPN also uses a Control Channel, where the TLS protocol is used. OpenVPN has **explicitly** disabled compression inside the Control Channel since OpenVPN 2.3.9 and OpenVPN 2.4.0 when compiled against OpenSSL. The compression on the Control Channel is not configurable. OpenVPN compiled against mbedTLS and PolarSSL has no support for modifying compression on the Control Channel, but it is disabled by default in the compiling process of the mbedTLS/PolarSSL library. No payload packets are sent over this channel and communication is strictly between openvpn server and client, making chosen plaintext like BEAST, CRIME and VORACLE extremely difficult for the Control Channel. == Mitigation == The compression feature in OpenVPN is dynamic and by using the `--compress` or `--comp-lzo` options, the wire protocol used between the OpenVPN clients and server changes slightly, to encapsulate packets in what is referred to as a `compression frame`. This does not mean data this frame carries is always compressed, but it *might* be compressed, all depending on a flag in the frame header. It is important to remember that `--comp-lzo` or `--compress` must be used on both the local and the remote side. If only one side uses any of these options, it will not be a functional VPN tunnel. Further, `--comp-lzo` and `--compress` have overlapping feature support, meaning that `--compress lzo` is identical to `--comp-lzo yes`or `--comp-lzo adaptive`. To mitigate the VORACLE attack you can thus disable compression in the configuration file without breaking other connections during a gradual configuration update. And *ONLY* use these options *if* you already use `--comp-lzo` or `--compress` in your configuration. === Community edition: OpenVPN 2.3.x and OpenVPN 2.4.x === If a soft migration is not needed you can remove all `comp-lzo` and `compress` from all clients and server configs to disable compression. On the server side use: - OpenVPN 2.4.0 newer and only OpenVPN 2.4.x or newer clients: Use `--compress stub-v2` and `--push "compress stub-v2"` - OpenVPN 2.3.X and older: Use `--comp-lzo no` and `--push "comp-lzo no"` This ensures the server will not initially try to use compression, and tells clients to not use it either. All of this keeps the compression framing intact and ensures backwards compatibility with clients not pulling in pushed options. On the client side: Compression on the client side needs to match the server configuration (either explicit with the right `compress`/`comp-lzo` config option or implicit through pushed option). A client side mitigation is therefore currently not possible in all scenarios without upgrading the client. - OpenVPN 2.4.0 and newer, and server respecting client capabilities: This is only valid for servers that respect the capabilities that the client sends to it (for example OpenVPN Access server) replace the `comp-lzo no` option with `comp-lzo stub`. This will stop the client from announcing compression support (via `IV_LZO=1`, `IV_LZ4=1` etc) and only advertises stub support. If your connection stops working after this change your server does not respect the client capabilities. === Commercial products: Access Server === The compression feature is enabled by default. It can be disabled under Advanced VPN, "Default Compression Settings" setting. The same can be achieved via the command line: {{{ /usr/local/openvpn_as/scripts/sacli --user '__DEFAULT__' -k prop_lzo -v false UserPropPut }}} Access Server allows also to set compression on a per user basis. If a user setting is present, it overrides the default setting. For a client side mitigation replace the `comp-lzo no` in the client config with `compress stub`. === Commercial products: OpenVPN Connect === Inside the OpenVPN Connect app, open the left-side menu inside the "Access Server" and "OVPN Profile" sections and click on the "Settings" menu item. Scroll down to the "Compression" section and select "Downlink Only". This will ensure that the client will not try to compress any packets but still accepts compressed packets from the server. === Commercial products: Private Tunnel === Neither the Private Tunnel app nor the service facilitates the compression feature, no need to change anything. == But I really need compression == In most cases this is more a perceived need than a real need. - Most traffic is not compressible since it is either already compressed (e.g. large downloads) or is encrypted and cannot be compressed. - VPN compression is fairly inefficient compared to normal compression. Only one packet at a time (~1400 bytes) is compressed. It is always better compress data at a higher protocol layer. == The plan forward == There are on-going discussions in the [https://www.mail-archive.com/openvpn-devel@lists.sourceforge.net/msg17417.html OpenVPN developers community] on how to resolve this better in future releases. Changes will be applied to both the OpenVPN 2.x community versions, OpenVPN 3 Core library. These changes will also propagate into our commercial offering as new defaults. There is consensus about disabling compression by default when the local OpenVPN process sends data to a remote OpenVPN process, but will accept compressed packets from the remote side. This is called asymmetric compression. The advantage of this approach is that it does not break any existing configurations. The `--comp-lzo` and `--compress` options will then primarily just enable the compression framing. [[br]] The `lzo` and `lz4` options which `--compress` takes then define which decompression algorithm to use. Currently the biggest disagreement is if it should be allowed or even possible to enable symmetric compression - which allows the local side to compress the data it sends to the remote side.