Skip to content

Bluetooth characteristic LESC security requirement not enforced without additional flags

High
ceolin published GHSA-p6f3-f63q-5mc2 Feb 19, 2024

Package

No package listed

Affected versions

<= 3.5.0

Patched versions

None

Description

Summary

The documentation specifies that the BT_GATT_PERM_READ_LESC and BT_GATT_PERM_WRITE_LESC defines for a Bluetooth characteristic: Attribute read/write permission with LE Secure Connection encryption. If set, requires that LE Secure Connections is used for read/write access, however this is only true when it is combined with other permissions, namely BT_GATT_PERM_READ_ENCRYPT/BT_GATT_PERM_READ_AUTHEN (for read) or BT_GATT_PERM_WRITE_ENCRYPT/BT_GATT_PERM_WRITE_AUTHEN (for write), if these additional permissions are not set (even in secure connections only mode) then the stack does not perform any permission checks on these characteristics and they can be freely written/read.

Details

File subsys/bluetooth/host/gatt.c lines 3072 onwards has:

uint8_t bt_gatt_check_perm(struct bt_conn *conn, const struct bt_gatt_attr *attr,
                        uint16_t mask)
{
        if ((mask & BT_GATT_PERM_READ) &&
            (!(attr->perm & BT_GATT_PERM_READ_MASK) || !attr->read)) {
                return BT_ATT_ERR_READ_NOT_PERMITTED;
        }

        if ((mask & BT_GATT_PERM_WRITE) &&
            (!(attr->perm & BT_GATT_PERM_WRITE_MASK) || !attr->write)) {
                return BT_ATT_ERR_WRITE_NOT_PERMITTED;
        }

        if (IS_ENABLED(CONFIG_BT_CONN_DISABLE_SECURITY)) {
                return 0;
        }

        mask &= attr->perm;

        /*
         * Core Specification 5.4 Vol. 3 Part C 10.3.1
         *
         * If neither an LTK nor an STK is available, the service
         * request shall be rejected with the error code
         *  ^`^|Insufficient Authentication ^`^}.
         * Note: When the link is not encrypted, the error code
         *  ^`^|Insufficient Authentication ^`^} does not indicate that
         *  MITM protection is required.
         *
         * If an LTK or an STK is available and encryption is
         * required (LE security mode 1) but encryption is not
         * enabled, the service request shall be rejected with
         * the error code  ^`^|Insufficient Encryption ^`^}.
         */

        if (mask & (BT_GATT_PERM_ENCRYPT_MASK | BT_GATT_PERM_AUTHEN_MASK)) {
#if defined(CONFIG_BT_SMP)
                if (!conn->encrypt) {
                        if (bt_conn_ltk_present(conn)) {
                                return BT_ATT_ERR_INSUFFICIENT_ENCRYPTION;
                        } else {
                                return BT_ATT_ERR_AUTHENTICATION;
                        }
                }

                if (mask & BT_GATT_PERM_AUTHEN_MASK) {
                        if (bt_conn_get_security(conn) < BT_SECURITY_L3) {
                                return BT_ATT_ERR_AUTHENTICATION;
                        }
                }

                if (mask & BT_GATT_PERM_LESC_MASK) {
                        const struct bt_keys *keys = conn->le.keys;

                        if (!keys || (keys->flags & BT_KEYS_SC) == 0) {
                                return BT_ATT_ERR_AUTHENTICATION;
                        }
                }

It is if (mask & (BT_GATT_PERM_ENCRYPT_MASK | BT_GATT_PERM_AUTHEN_MASK)) { that causes this issue

PoC

static ssize_t read_u8(struct bt_conn *conn, const struct bt_gatt_attr *attr, void *buf,
                       uint16_t len, uint16_t offset)
{
        const uint8_t *value = attr->user_data;
        printk("security level: %d\n", bt_conn_get_security(conn));
        return bt_gatt_attr_read(conn, attr, buf, len, offset, &value, sizeof(value));
}

static ssize_t write_u8(struct bt_conn *conn, const struct bt_gatt_attr *attr, const void *buf,
                        uint16_t len, uint16_t offset, uint8_t flags)
{
        uint8_t *value = attr->user_data;
        printk("security level: %d\n", bt_conn_get_security(conn));
        return sizeof(gatt_value);
}

BT_GATT_SERVICE_DEFINE(ess_svc,
        BT_GATT_PRIMARY_SERVICE(BT_UUID_ESS),

        /* Temperature Sensor 1 */
        BT_GATT_CHARACTERISTIC(BT_UUID_TEMPERATURE, (BT_GATT_CHRC_READ | BT_GATT_CHRC_WRITE),
                               (BT_GATT_PERM_READ_LESC | BT_GATT_PERM_WRITE_LESC), read_u8,
                               write_u8, &gatt_value),
);

The above is excerpts from code that show the issue, a device can connect and read/write and the handlers will run, security level: 1 can be seen. This is best shown when configured with CONFIG_BT_SMP_SC_ONLY=y and if a pairing cannot take place due to the zephyr bt_conn_set_security call failing.

Impact

Security permission bypass in applications that have assumed that the LESC permission defines work without combining them with other defines.

Patches

main: #69170

embargo: 2024-02-13

For more information

If you have any questions or comments about this advisory:

Severity

High

CVSS overall score

This score calculates overall vulnerability severity from 0 to 10 and is based on the Common Vulnerability Scoring System (CVSS).
/ 10

CVSS v3 base metrics

Attack vector
Network
Attack complexity
Low
Privileges required
None
User interaction
None
Scope
Unchanged
Confidentiality
High
Integrity
Low
Availability
None

CVSS v3 base metrics

Attack vector: More severe the more the remote (logically and physically) an attacker can be in order to exploit the vulnerability.
Attack complexity: More severe for the least complex attacks.
Privileges required: More severe if no privileges are required.
User interaction: More severe when no user interaction is required.
Scope: More severe when a scope change occurs, e.g. one vulnerable component impacts resources in components beyond its security scope.
Confidentiality: More severe when loss of data confidentiality is highest, measuring the level of data access available to an unauthorized user.
Integrity: More severe when loss of data integrity is the highest, measuring the consequence of data modification possible by an unauthorized user.
Availability: More severe when the loss of impacted component availability is highest.
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:L/A:N

CVE ID

CVE-2024-1638

Weaknesses

Credits