Blame

ba5529 Samuli Seppänen 2025-03-18 12:45:01 1
# VORACLE attack and OpenVPN 
2
3
## Background
4
5
Security researcher Ahamed Nafeez has [presented a new attack vector](https://speakerdeck.com/skepticfx/voracle-compression-oracle-attacks-on-vpn-tunnels) 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.
6
7
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:
8
9
10
* `--comp-lzo`
11
* `--comp-lzo yes`
12
* `--comp-lzo adaptive`
13
* `--compress lzo`
14
* `--compress lz4`
15
* `--compress lz4-v2`
16
17
Configurations *NOT* using `--comp-lzo` or `--compress` are *NOT* affected by VORACLE.
18
19
### Simplified Example
20
21
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.
22
23
Alice has setup a login page. To check passwords entered there, Alice sends a message like "tell me if <the password entered> matches <secret password>" to Bob.
24
The more similar the <the password entered> is to <secret password> 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.
25
26
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)
27
28
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.
29
30
### Compression is **NOT** enabled by default
31
32
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.
33
34
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.
35
36
## Mitigation
37
38
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.
39
40
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`.
41
42
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.
43
44
### Community edition: OpenVPN 2.3.x and OpenVPN 2.4.x
45
46
If a soft migration is not needed you can remove all `comp-lzo` and `compress` from all clients and server configs to disable compression.
47
48
On the server side use:
49
- OpenVPN 2.4.0 newer and only OpenVPN 2.4.x or newer clients: Use `--compress stub-v2` and `--push "compress stub-v2"`
50
- OpenVPN 2.3.X and older: Use `--comp-lzo no` and `--push "comp-lzo no"`
51
52
53
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.
54
55
On the client side:
56
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.
57
58
- OpenVPN 2.4.0 and newer, and server respecting client capabilities:
59
60
This is only valid for servers that respect the capabilities that the client sends to it (for example OpenVPN Access server)
61
62
63
replace the `comp-lzo no` option with `comp-lzo stub`.
64
65
66
This will stop the client from announcing compression support (via `IV_LZO=1`, `IV_LZ4=1` etc) and only advertises stub support.
67
68
If your connection stops working after this change your server does not respect the client capabilities.
69
70
71
72
73
### Commercial products: Access Server
74
75
The compression feature is enabled by default. It can be disabled under Advanced VPN, "Default Compression Settings" setting.
76
77
The same can be achieved via the command line:
78
79
```
80
/usr/local/openvpn_as/scripts/sacli --user '__DEFAULT__' -k prop_lzo -v false UserPropPut
81
```
82
83
Access Server allows also to set compression on a per user basis. If a user setting is present, it overrides the default setting.
84
85
For a client side mitigation replace the `comp-lzo no` in the client config with `compress stub`.
86
87
### Commercial products: OpenVPN Connect
88
89
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"
90
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.
91
92
93
### Commercial products: Private Tunnel
94
95
Neither the Private Tunnel app nor the service facilitates the compression feature, no need to change anything.
96
97
## But I really need compression
98
In most cases this is more a perceived need than a real need.
99
100
- Most traffic is not compressible since it is either already compressed (e.g. large downloads) or is encrypted and cannot be compressed.
101
- 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.
102
103
104
## The plan forward
105
106
There are on-going discussions in the [OpenVPN developers community](https://www.mail-archive.com/openvpn-devel@lists.sourceforge.net/msg17417.html) 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.
107
108
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.
109
110
The `--comp-lzo` and `--compress` options will then primarily just enable the compression framing.
111
The `lzo` and `lz4` options which `--compress` takes then define which decompression algorithm to use.
112
113
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.