QSB #056: Insufficient anti-spoofing firewall rules
We have just published Qubes Security Bulletin (QSB) #056: Insufficient anti-spoofing firewall rules. The text of this QSB is reproduced below. This QSB and its accompanying signatures will always be available in the Qubes Security Pack (qubes-secpack).
View QSB #056 in the qubes-secpack:
https://github.com/QubesOS/qubes-secpack/blob/master/QSBs/qsb-056-2019.txt
Learn about the qubes-secpack, including how to obtain, verify, and read it:
https://www.qubes-os.org/security/pack/
View all past QSBs:
https://www.qubes-os.org/security/qsb/
---===[ Qubes Security Bulletin #56]===---
2019-12-25
Insufficient anti-spoofing firewall rules
Summary
=======
The firewall configuration in Qubes OS prevents IP address spoofing in
downstream interfaces (e.g., network-providing qubes, network-consuming
qubes, and `vif*` interfaces). However, it does not prevent IP spoofing
in upstream interfaces (normally `eth0`, but in the case of VPNs or
other configuration, there may also be others).
Impact
======
Configurations with inter-VM networking allowed [1] or additional
interfaces created (e.g., VPNs) are vulnerable to IP spoofing. Combined
with other vulnerabilities, such as the procedure described in the
CVE-2019-14899 report [2], this could allow an upstream qube (e.g.,
sys-net) to inject data into an established connection.
Discussion
==========
The anti-spoofing firewall rules in a network-providing qube look like
this:
*raw
...
-A PREROUTING ! -s 10.137.0.5/32 -i vif12.0 -j DROP
-A PREROUTING ! -s 10.137.0.6/32 -i vif17.0 -j DROP
-A PREROUTING ! -s 10.137.0.7/32 -i vif18.0 -j DROP
-A PREROUTING ! -s 10.137.0.8/32 -i vif21.0 -j DROP
COMMIT
Each `vif*` interface drops packets if its source IP does not match the
one assigned to the qube behind that interface. However, it does not
ensure that the source IP does not appear on any other (non-`vif`)
interface.
The other property could, in theory, be achieved by this FORWARD chain:
*filter
...
-A FORWARD -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A FORWARD -j QBS-FORWARD
-A FORWARD -i vif+ -o vif+ -j DROP
-A FORWARD -i vif+ -j ACCEPT
-A FORWARD -j DROP
COMMIT
These rules should reject packets not belonging to established
connections on non-vif interfaces. Moreover, without seeing other
packets in the connection, it should be prohibitively difficult to forge
packets that would be considered to be part of an established
connection. However, methods like the one described in the
CVE-2019-14899 report [2] allow one to guess the required parameters.
Note that if a connection normally goes through a given qube (without
any further protection like TLS), that qube can always manipulate the
traffic without guessing anything.
The default Qubes configuration is secure, since network traffic either
goes directly to the upstream qube (which, by definition, has access to
that traffic), or it is an inter-VM connection attempt, which is
prevented by the third rule (meaning that there are no connections in
the conntrack table that the upstream qube could try to hijack).
However, once the user departs from the default configuration, e.g., by
introducing inter-VM communications [1] (allowing traffic between some
`vif*` interfaces), or VPN-like interfaces, the default rules are no
longer sufficient, since an upstream qube can inject packets (by
spoofing the source IP) into connections that normally do not pass
through it in the clear.
Our solution to this problem is twofold:
1. For Qubes OS 4.0, whenever a running qube is connected to a
network-providing qube, an additional firewall rule is added that
blocks the running qube's IP as a source on other network interfaces.
2. For Qubes OS 4.1 and later, we will modify the firewall mechanism so
that it maintains aa list of connected qubes and their addresses,
even when they are not running. All such addresses will be rejected
on upstream network interfaces.
The main difference between these two solutions is that fix for Qubes OS
4.0 does not protect against spoofing the addresses of qubes that are
not running. However, since 4.0 is a stable release, we must consider
the impact of such a solution on the stability of this release. This fix
is a much simpler change that carries a considerably lower risk of
introducing a regression.
Patching
========
The specific packages that resolve the problems discussed in this
bulletin are as follows:
For Qubes OS 4.0:
- qubes-core-agent version 4.0.51
The packages for domUs are to be installed in TemplateVMs and
StandaloneVMs via the Qube Manager or via their respective package
managers:
For updates to Fedora from the stable repository
(not immediately available):
$ sudo dnf update
For updates to Fedora from the security-testing repository:
$ sudo dnf update --enablerepo=qubes-vm-*-security-testing
For updates to Debian from the stable repository
(not immediately available):
$ sudo apt update && sudo apt dist-upgrade
For updates to Debian from the security-testing repository:
First, uncomment the line below "Qubes security updates testing
repository" in:
/etc/apt/sources.list.d/qubes-r*.list
Then:
$ sudo apt update && sudo apt dist-upgrade
A restart is required for these changes to take effect. This entails
shutting down the TemplateVM before restarting all the TemplateBasedVMs
based on that TemplateVM.
These packages will migrate from the security-testing repositories to
their respective current (stable) repositories over the next two weeks
after being tested by the community.
Credits
========
The issue was reported by Demi Marie Obenour.
References
==========
[1] https://www.qubes-os.org/doc/firewall/#enabling-networking-between-two-qubes
[2] https://nvd.nist.gov/vuln/detail/CVE-2019-14899
--
The Qubes Security Team
https://www.qubes-os.org/security/