Safeguard
Supply Chain Security•

Bluetooth LE GATT Explained: Services, Pairing, Bonding and Security

GATT is how Bluetooth LE devices expose data as services and characteristics over ATT. How pairing, bonding and attribute permissions protect it.

Safeguard Security Team
33 min read

Bluetooth Low Energy (LE) devices expose their data through GATT, the Generic Attribute Profile: a server holds a table of attributes grouped into services and characteristics, and a client discovers, reads, writes and subscribes to them using the Attribute Protocol (ATT). Whether any of that is protected depends on pairing, bonding and per attribute permissions defined by the Security Manager and the Generic Access Profile, all part of the Bluetooth Core Specification, which is at version 6.3 on bluetooth.com today.

This post follows a BLE connection the way the specification describes it: advertising and connection setup, ATT, the GATT structure on top, the Security Manager's pairing methods, security modes and levels, and the privacy feature. Then it covers the weakness classes that follow from the design and the BlueZ commands a defender uses to check hosts and devices they own. For the firmware side, see whether a Wi-Fi or Bluetooth module blob belongs in your SBOM.

Key takeaways

  • BLE, ATT, GATT and the Security Manager arrived together in Bluetooth Core 4.0 (June 2010, per NIST SP 800-121 Rev. 2). The current version listed by the Bluetooth SIG is Core 6.3.
  • ATT runs on the LE fixed L2CAP channel 0x0004. The default LE ATT_MTU is 23 octets, attribute values are at most 512 octets, and handles are 16 bit.
  • GATT declares services with UUID 0x2800 or 0x2801 and characteristics with 0x2803. Clients enable notifications and indications by writing the Client Characteristic Configuration descriptor, 0x2902.
  • Attribute permissions are set by the server and cannot be discovered over ATT. Characteristic properties say what operations exist, not who may perform them.
  • Just Works pairing encrypts but gives no protection against an active man in the middle. In LE Legacy Pairing, no method protects against a passive eavesdropper during pairing; LE Secure Connections (from 4.2) does.
  • LE security mode 1 level 4 means authenticated LE Secure Connections pairing with a 128-bit key. NIST strongly recommends it. Core 6.3 removed data signing, and with it LE security mode 2.

What BLE, ATT and GATT are for, the layer and the standard

Bluetooth LE serves devices that send small amounts of data occasionally and must run for a long time on small batteries: sensors, wearables, locks, medical devices, trackers. NIST SP 800-121 Rev. 2 notes that its predecessor was introduced by Nokia in 2006 as Wibree and became part of Bluetooth 4.0 in 2010. The Core change history lists what 4.0 added for LE: the LE physical and link layers, AES encryption, L2CAP and GAP enhancements, ATT, GATT and the Security Manager.

LayerWhat it does
LE radio40 RF channels in the 2.4 GHz band; LE 1M, LE 2M and LE Coded PHYs
Link Layer (Vol 6, Part B)Advertising, connection setup, connection events, AES-CCM link encryption
HCIInterface between the host stack and the controller chip
L2CAPChannels; fixed channel 0x0004 carries ATT, another fixed channel carries SMP
Security Manager (Vol 3, Part H)Pairing, key generation and key distribution
ATT (Vol 3, Part F)Client and server protocol for finding, reading, writing, notifying and indicating attributes
GATT (Vol 3, Part G)Services, characteristics, descriptors and the procedures that use them
GAP (Vol 3, Part C)Roles, discovery, bonding, security modes and levels, privacy

GATT and GAP are profiles: they define how ATT and SMP are used, not new wire formats.

The defining document is the Bluetooth Core Specification from the Bluetooth SIG. On 23 October 2026 the SIG's specifications list showed Core 6.3 as the latest adopted version, with 6.2, 6.1 and 6.0 also adopted and 5.4 and earlier listed as amended versions. Each version supersedes the previous one as the reference, and the change history records features added, deprecated and removed. Two companions matter for GATT: the Assigned Numbers document (version dated 22 October 2026 when fetched), which lists SIG UUIDs such as 0x1800 for the GAP service, 0x1801 for the GATT service and 0x180A for Device Information, and the GATT Specification Supplement, which defines characteristic formats. Outside the SIG, the reference is NIST SP 800-121 Rev. 2, Guide to Bluetooth Security, May 2017 with updates as of 19 January 2022.

How BLE works on the wire

Advertising and connection setup

The link layer splits the 40 RF channels into 3 primary advertising channels and 37 general purpose channels used for secondary advertising, periodic advertising and data. Advertising packets on the primary channels use the fixed Access Address 0x8E89BED6. Legacy advertising PDU types include ADV_IND, ADV_DIRECT_IND, ADV_NONCONN_IND and ADV_SCAN_IND; a scanner can send SCAN_REQ and get SCAN_RSP, and a Central opens a connection with CONNECT_IND. Advertising payloads are readable by anyone in range. Core 5.4 added an Encrypted Advertising Data procedure for products that need to protect them.

A connection from start to finish

Central (client)                                  Peripheral (server)
   |  <---- ADV_IND on primary advertising channels ---|  public
   |  ----- CONNECT_IND ------------------------------>|  link layer connection
   |  ----- ATT_EXCHANGE_MTU_REQ (Client Rx MTU) ----->|  ATT on L2CAP CID 0x0004
   |  <---- ATT_EXCHANGE_MTU_RSP (Server Rx MTU) ------|  both use the smaller value
   |  ----- ATT_READ_BY_GROUP_TYPE_REQ (0x2800) ------>|  discover primary services
   |  <---- ATT_READ_BY_GROUP_TYPE_RSP ----------------|
   |  ----- ATT_READ_BY_TYPE_REQ (0x2803) ------------>|  discover characteristics
   |  <---- ATT_READ_BY_TYPE_RSP ----------------------|
   |  ----- ATT_READ_REQ (protected handle) ---------->|
   |  <---- ATT_ERROR_RSP Insufficient Authentication -|  0x05
   |  ===== SMP pairing, then AES-CCM encryption ======|
   |  ----- ATT_READ_REQ (same handle) --------------->|
   |  <---- ATT_READ_RSP (value) ----------------------|
   |  ----- ATT_WRITE_REQ (CCCD = 0x0001) ------------>|  enable notifications
   |  <---- ATT_HANDLE_VALUE_NTF ----------------------|  unsolicited updates
   |  ----- link layer disconnect -------------------->|  ATT bearer ends with the link

On the LE fixed channel the ATT bearer exists as soon as the link does and ends only when the link disconnects. Core 5.2 added Enhanced ATT bearers over L2CAP credit based channels.

ATT: attributes, handles and PDUs

Each attribute has a type (a UUID), a 16 bit handle and permissions defined by the higher layer, which the ATT text says "cannot be accessed using the Attribute Protocol". Handles are unique and non-zero; 0x0000 is reserved and 0xFFFF is the maximum. 32 bit UUIDs are converted to 128 bit inside ATT PDUs. An attribute value is at most 512 octets; values longer than ATT_MTU minus 1 are read with ATT_READ_BLOB_REQ and written with prepare and execute writes, which are not atomic. ATT is sequential: one outstanding request per bearer, and a transaction not completed within 30 seconds times out and closes the bearer to further ATT traffic.

FieldSizeMeaning
Attribute Opcode1 octetBits 5 to 0: Method. Bit 6: Command Flag (a command gets no response). Bit 7: previously used
Attribute Parameters0 to ATT_MTU minus 1 octetsMethod specific; multi-octet fields little endian except the value

PDUs are commands, requests, responses, notifications, indications and confirmations. Selected opcodes from the Core 6.3 summary:

PDUOpcodeUse
ATT_ERROR_RSP0x01Request opcode, handle in error and error code
ATT_EXCHANGE_MTU_REQ / RSP0x02 / 0x03Negotiate ATT_MTU
ATT_FIND_INFORMATION_REQ / RSP0x04 / 0x05List handles and types
ATT_READ_BY_TYPE_REQ / RSP0x08 / 0x09Characteristic discovery
ATT_READ_REQ / RSP0x0A / 0x0BRead by handle
ATT_READ_BLOB_REQ / RSP0x0C / 0x0DRead part of a long value
ATT_READ_BY_GROUP_TYPE_REQ / RSP0x10 / 0x11Service discovery
ATT_WRITE_REQ / RSP0x12 / 0x13Write with acknowledgement
ATT_WRITE_CMD0x52Write without response
ATT_HANDLE_VALUE_NTF0x1BServer push, no confirmation
ATT_HANDLE_VALUE_IND / CFM0x1D / 0x1EServer push with confirmation

Opcode 0xD2 is marked "previously used": it was the signed write command, gone with data signing in Core 6.3. On the LE fixed channel the default ATT_MTU is 23, so a single read response carries at most 22 octets of value. On BR/EDR the minimum ATT_MTU is 48.

GATT: services, characteristics and descriptors

A profile is made of services; a service of characteristics and included services; a characteristic of a value plus optional descriptors. Every element is an attribute.

GATT elementAttribute typeAttribute value
Primary / secondary service0x2800 / 0x2801Service UUID
Include0x2802Handle range and UUID of the included service
Characteristic declaration0x2803Properties, value handle, characteristic UUID
Characteristic valueThe characteristic UUIDThe data
Extended Properties / User Description0x2900 / 0x2901Extra property bits / UTF-8 text
Client Characteristic Configuration (CCCD)0x2902Notification and indication bits

The declaration's properties are set, the specification says, "without regard to security requirements":

PropertyBitAllows
Broadcast0x01Value in advertising data
Read0x02Reads
Write Without Response0x04ATT_WRITE_CMD
Write0x08ATT_WRITE_REQ and long writes
Notify / Indicate0x10 / 0x20Server pushes; a CCCD must exist
(previously used)0x40Was authenticated signed writes
Extended Properties0x80Extended Properties descriptor exists

Properties tell a client what operations exist. Permissions, which the client cannot see, decide whether this client on this link may perform them.

Reads, writes, notifications and caching

Discover All Primary Services sends ATT_READ_BY_GROUP_TYPE_REQ for 0x2800 across handles 0x0001 to 0xFFFF; characteristic discovery reads 0x2803 declarations within a service's range. Notifications and indications stay off until the client writes the CCCD: bit 0 for notifications, bit 1 for indications, default 0x0000, and one CCCD per client per characteristic.

Clients cache the attribute table. If handles can change, for example after a firmware update, the server exposes Service Changed (0x2A05) and indicates the affected range. Core 5.1 added the Database Hash (0x2B2A) and Robust Caching, so a client that missed a change gets a Database Out Of Sync error instead of using stale handles. The cache is valid across connections only for bonded clients, and the server must store service changed information for bonded devices.

Pairing, bonding and the Security Manager

The Core architecture lists five security features: pairing (creating shared keys), bonding (storing them for later connections), device authentication, encryption and message integrity. GAP defines bondable and non-bondable modes; a non-bondable device refuses pairing that would result in a bond.

The three phases

  1. Pairing Feature Exchange. Each side sends its IO capability, OOB data flag, authentication requirements (bonding, MITM, Secure Connections), maximum key size and the keys it wants to distribute. The SC flag selects LE Secure Connections or LE Legacy Pairing.
  2. Key generation. Legacy pairing derives a Temporary Key (TK) and a Short Term Key (STK). Secure Connections runs ECDH on P-256 and derives a Long Term Key (LTK) with the AES-CMAC based function f5.
  3. Key distribution. On the encrypted link, devices can send the Identity Resolving Key (IRK) and Identity Address, and in legacy pairing the LTK with its EDIV and Rand.

SMP has its own 30 second timer; on expiry pairing fails and no more SMP commands may be sent on that link.

The four association models

Each device maps its input and output to one of NoInputNoOutput, DisplayOnly, DisplayYesNo, KeyboardOnly or KeyboardDisplay.

MethodUser's partMITM protectionAvailable in
Just WorksNoneNoneLegacy and Secure Connections
Passkey Entry6 digit passkey shown on one device and typed on the other, or typed on bothYesBoth
Numeric ComparisonConfirm two displayed 6 digit values matchYesSecure Connections only
Out of BandData over another channel such as NFCYes, if that channel resists eavesdropping and MITMBoth

If neither device sets the MITM flag, IO capabilities are ignored and Just Works is used. Legacy pairing uses OOB only if both sides have OOB data; Secure Connections uses it if either does. Otherwise a table of IO capability pairs decides, and a NoInputNoOutput device ends up with Just Works. Passkeys must be random between 000,000 and 999,999; Secure Connections commits to them one bit per round over 20 rounds. For Numeric Comparison the Core says a simple MITM produces mismatching values with probability 0.999999.

LE Legacy Pairing versus LE Secure Connections

PropertyLE Legacy Pairing (4.0, 4.1)LE Secure Connections (from 4.2)
Key agreementTK by method, STK derivedP-256 ECDH, LTK via f5
Passive eavesdropper during pairingNo method protectsProtected
Authenticated MITM protectionOnly OOB with 128 bits of entropyPasskey, Numeric Comparison or OOB
LTKDistributed in Phase 3Computed by both, never sent
Highest LE level34

The Core is blunt about legacy pairing: "none of the pairing methods provide protection against a passive eavesdropper during the pairing process as predictable or easily established values for TK are used." Pairing done with no eavesdropper present still gives confidentiality afterwards. NIST describes the same arc: 4.0 brought AES-CCM, and 4.2 added Secure Connections with AES-CMAC and P-256.

Key sizes run from 7 to 16 octets. The smaller maximum wins, each side rejects a result below its own minimum, and shorter keys are made by masking a 128-bit key, so 7 octets means 56 bits. A server answers Encryption Key Size Too Short (0x0C) when an attribute needs more.

Security modes and levels and attribute permissions

Core 6.3 has two LE security modes. Mode 1 covers connections:

LevelMeaning
1No security: no authentication, no encryption
2Unauthenticated pairing with encryption (for example Just Works)
3Authenticated pairing with encryption
4Authenticated LE Secure Connections pairing with encryption using a 128-bit strength key

Each level satisfies those below it. Mode 3 covers broadcast isochronous streams, with levels for no security and unauthenticated or authenticated Broadcast_Codes. Mode 2, built on data signing, is gone: GAP says it "was part of the data signing feature, which has been deprecated and removed", and the change history lists data signing as removed in 6.3. NIST SP 800-121 Rev. 2 still describes mode 2 because it predates the change.

In Secure Connections Only mode a device uses only mode 1 level 4, except for services needing just level 1, and accepts new service connections only from peers using authenticated Secure Connections pairing. NIST calls level 4 the most secure option and strongly recommends it for 4.2 and later; for 4.0 and 4.1 it recommends level 3, says level 1 "should never be used", and warns that Secure Connections Only is not backward compatible with 4.0 and 4.1 devices.

ATT permissions combine access (read, write or both), encryption, authentication and authorisation, per attribute. A server can allow reads when encrypted but writes only when authenticated. When a request falls short:

ErrorCodeMeaning
Insufficient Authentication0x05Pair or upgrade pairing, then retry
Insufficient Authorization0x08Application has not authorised this client
Encryption Key Size Too Short0x0CRe-pair with a longer key
Insufficient Encryption0x0FStart encryption with an existing key

Three rules from the ATT and GATT security considerations shape designs. Discovery must always be permitted, so a device cannot hide its GATT table. A server must check authentication and authorisation before anything else, or error differences could reveal the size of a protected value. And bearers between the same devices may have different security, so authentication on one does not imply it on another. Core 5.4 added the LE GATT Security Levels characteristic (0x2BF5) so a server can publish its highest requirement and a client can pair at the right level up front.

Privacy: identity addresses and resolvable private addresses

Every device has an Identity Address: a public address or a random static address. The privacy feature exists, in GAP's words, to make it "more difficult for an attacker to track a device over a period of time".

Bits 47 and 46Random address sub-type
0b11Static device address
0b01Resolvable private address (RPA)
0b00Non-resolvable private address
0b10Reserved

An RPA is a 24-bit random part followed by a 24-bit hash of it under the device's 128-bit IRK. Bonded peers with the IRK recognise the device; others see an address that rotates. GAP's TGAP(private_addr_int) timer has a recommended maximum of 15 minutes, and Core 6.1 added Randomized RPA Updates. GAP also advises changing advertising data in step with the address, since a stable payload identifies the device anyway. Privacy is optional for every role.

Versions and history

Core versionAdoptedLE security and GATT changes
4.0June 2010 (NIST)LE, AES-CCM, ATT, GATT, Security Manager, legacy pairing
4.1December 2013 (NIST)LE privacy 1.1, 32-bit UUIDs, LE L2CAP channels
4.2December 2014 (NIST)LE Secure Connections, link layer privacy, data length extension
5.0Not confirmed2M and Coded PHYs, advertising extensions
5.1Not confirmedGATT caching; security erratum 10734 on pairing
5.2Not confirmedEnhanced ATT, LE isochronous channels
5.4Not confirmedEncrypted Advertising Data, LE GATT Security Levels characteristic
6.0Not confirmedChannel Sounding
6.1Not confirmedRandomized RPA Updates
6.2Not confirmedSecurity errata on passkey generation, random number sources and legacy pairing reflection
6.3Not confirmedData signing removed

The 6.2 errata double as a checklist for older products: implementations "may generate insecure Passkeys", legacy pairing may be open to reflection of Random and Confirm values, random numbers may not come from secure generators, and conforming implementations must not let users set the key size or keep a fixed key pair when they can generate one. A box's version number says little; the link uses what both devices support and request, so check the actual pairing.

Security properties: what BLE does and does not guarantee

PropertyWhat the specification providesWhere it falls short
ConfidentialityAES-CCM after pairing or with a bondAdvertising and unencrypted connections are cleartext; captured legacy pairings can be decrypted
IntegrityA MIC on non-empty PDUs on encrypted connectionsNone on unencrypted links; the CRC is not cryptographic
Peer authenticationPasskey, Numeric Comparison or OOBJust Works authenticates nothing
AuthorisationPer attribute permission and error 0x08How it happens is implementation defined
PrivacyRPAs and rotationOptional; undone by stable payloads
AvailabilitySupervision timeoutsRadio jamming is outside any protocol

BLE security is opt in at every layer. The product's permission table, pairing configuration and privacy settings decide whether the tools are used.

Weakness classes, explained as concepts

Unauthenticated characteristics

The most common weakness is not cryptographic. A characteristic that changes state (unlock, dose, configuration, reset) has the Write property and no security permission, so any device in range can write it, and discovery makes it easy to find. Anything that changes state or exposes personal data should need at least encryption; anything safety relevant should need level 3 or 4. A PIN inside the payload on an unencrypted link is no substitute.

Just Works and missing MITM protection

Just Works encrypts but authenticates nobody, so an active attacker present during pairing can sit in the middle unnoticed, and over legacy pairing a passive recording of the pairing exposes the keys. Devices without a display or keypad should use OOB (NFC, a printed code, factory provisioning), sensitive services should require MITM protection, and pairing should be a deliberate, time limited action.

Downgrade and method confusion

Pairing strength is negotiated from what each side claims, so accepting legacy or unauthenticated methods lets a man in the middle steer toward them. The SIG's notice "Pairing Mode Confusion in Bluetooth LE Passkey Entry" (9 December 2022, CVE-2022-25836) is one published case. Secure Connections Only mode and refusing to downgrade an existing bond are the structural defences.

Key validation and cross transport overwrite

The SIG notice "Validation of Elliptic Curve Parameters" (23 July 2018, CVE-2018-5383) concerned implementations that did not sufficiently validate the peer's public key. "Exploiting Cross-Transport Key Derivation" (9 September 2020, CVE-2020-15802) concerned dual mode devices where a key from one transport could replace a stronger bond on the other. A key exchange is only as strong as its input validation and its rules for replacing keys.

Injection into unencrypted connections

The SIG notice "InjectaBLE" (21 June 2021, CVE-2021-31615) covered injecting traffic into established LE connections. On encrypted links the MIC rejects forged packets; unencrypted links have no cryptographic integrity, which is why every connection that carries commands should be encrypted.

Address tracking

A public or never changing address, or a serial number in advertising data, lets anyone follow a device. Privacy helps only if enabled and paired with a payload that does not identify the device. Bonded peers hold the IRK permanently, so prune bonds when a device changes hands.

Firmware update characteristics

Over the air updates are usually a vendor defined GATT service with a control point and a data characteristic. If it accepts writes from an unauthenticated peer, or the bootloader runs an unsigned image, the radio becomes a path to replace the device's code. Link security decides who may send an image; signature verification decides whether it runs. A product needs both.

Implementation bugs

Many Bluetooth vulnerabilities live in host stacks, controller firmware and the code that parses ATT, L2CAP and advertising data, plus application callbacks on every write. Length checks, bounds on queued writes and the 512 octet limit are ordinary input validation on an interface anyone nearby can reach.

Secure configuration, with defender side check commands

These checks come from the official BlueZ documentation in the BlueZ source tree on git.kernel.org: the bluetoothctl, bluetoothctl-gatt and bluetoothctl-mgmt manuals, the btmon manual and its SMP section, and the default main.conf. Only run them against systems you own or are authorised to test, and only against Bluetooth devices you own.

1. Inventory controllers and bonds

bluetoothctl show
bluetoothctl devices Paired
bluetoothctl devices Bonded
bluetoothctl devices Trusted
bluetoothctl info 00:11:22:33:44:55

show and info report the Adapter and Device properties. Look for unknown bonds, devices marked Trusted that should not be, and adapters left pairable or discoverable. The manual documents untrust, block and remove to clean up, and a here document form for scheduled checks:

bluetoothctl <<EOF
show
devices Bonded
EOF

2. Control pairing on the host

bluetoothctl pairable off

pairable off rejects pairing requests. The agent's capability is the host's IO capability; the documented values are DisplayOnly, DisplayYesNo, KeyboardDisplay, KeyboardOnly and NoInputNoOutput. NoInputNoOutput forces Just Works with every peer, so prefer KeyboardDisplay where a person is present. The management submenu sets controller level switches:

[bluetooth]# mgmt.info
[bluetooth]# mgmt.sc only
[bluetooth]# mgmt.privacy on
[bluetooth]# mgmt.io-cap KeyboardDisplay

Per the bluetoothctl-mgmt manual, sc takes on, off or only, privacy takes an optional IRK and io-cap sets the IO capability. These are runtime settings; persist them in main.conf.

3. Persist settings in main.conf

[General]
# Default "on"; "only" allows only Secure Connections
SecureConnections = only
# Default "off"
Privacy = device
# Default "never"
JustWorksRepairing = never
# Default false
AlwaysPairable = false
# Default 0, which means pairable forever
PairableTimeout = 120

[GATT]
# Minimum key size for secured characteristics: 0 or 7 to 16, default 0
KeySize = 16

Test SecureConnections = only with your real devices, since peers without Secure Connections will be refused. The file notes that network privacy mode may break older devices, which is why device mode is gentler. Leave [GATT] Security at its default of auto: setting it to low "disables GATT server attribute permissions".

4. Read a device's GATT table

[bluetooth]# gatt.list-attributes 00:11:22:33:44:55
[bluetooth]# gatt.attribute-info 0x2A00
[bluetooth]# gatt.select-attribute /org/bluez/hci0/dev_00_11_22_33_44_55/service001a/char001c
[bluetooth]# gatt.read

attribute-info shows a characteristic's flags, which are properties, not permissions. The real test on a device you own is whether reading or writing a sensitive characteristic over an unpaired link returns Insufficient Authentication or Insufficient Encryption. If it succeeds, the permission table is too open.

5. Watch pairing with btmon

sudo btmon -w pairing.btsnoop
btmon -r pairing.btsnoop > output.txt
grep -n "Pairing Request\|Pairing Response\|Pairing Failed\|Encryption Change" output.txt
grep -n "Authentication Insufficient\|Insufficient Encryption\|Insufficient Security\|security block" output.txt

The btmon SMP documentation explains the fields: the SC flag in the authentication requirement means Secure Connections and its absence means legacy pairing, the IO capability determines the method, and key distribution shows which keys will be sent. Treat the capture as a secret: btmon decodes distributed keys in the clear, including the IRK and, for legacy pairing, the LTK with EDIV and Rand.

Where NIST guidance fits

NIST SP 800-121 Rev. 2 includes a Bluetooth security checklist. Its LE advice matches the above: level 4 where both sides support it, level 3 for 4.0 and 4.1 devices, never level 1, and an inventory of devices. Read it alongside the current Core, since it predates the removal of data signing.

When to use BLE versus the alternatives

NeedBLE with GATTClassic Bluetooth (BR/EDR)ThreadWi-Fi
Typical useSensors, wearables, accessories, provisioningAudio streaming, older profilesLow power home and building devices needing IPHigh bandwidth devices, cameras
AddressingBluetooth addresses, optional RPAsBluetooth addressIPv6, per the Thread GroupIP
Security modelSMP pairing and bonding, per attribute permissionsSecure Simple Pairing or BR/EDR Secure ConnectionsNetwork layer security, per the Thread GroupNetwork access control plus the application
PowerVery lowHigher than LELow, on IEEE 802.15.4Highest
Cost of doing it securelyPairing UX and a permission tablePairing UX and key size rulesCommissioning and network credentialsCredential distribution and segmentation

A common pattern uses BLE for setup, then Thread or Wi-Fi for ongoing traffic. BLE then carries credentials for the other network, so the provisioning service needs level 3 or 4 even if nothing else does. The MQTT 5 explainer covers what often runs over that second network.

Common mistakes

  • Treating properties as permissions. Read and Write bits are set without regard to security.
  • Leaving state changing characteristics at level 1. Require encryption at minimum.
  • Shipping NoInputNoOutput everywhere. It guarantees Just Works; use OOB through NFC or a printed code instead.
  • Allowing legacy pairing when both sides support Secure Connections.
  • Relying on an application PIN over an unencrypted link. It travels in cleartext.
  • Accepting short keys. Set a 16 octet minimum for sensitive services.
  • Leaving the host pairable forever. BlueZ's default PairableTimeout of 0 means forever.
  • Enabling privacy but advertising a serial number.
  • Unsigned firmware over GATT.
  • Keeping btsnoop captures that contain live keys.
  • Following pre 6.3 guidance on signed writes and LE security mode 2.

FAQ

What is GATT in Bluetooth Low Energy?

The Generic Attribute Profile organises a BLE device's data into services, characteristics and descriptors on top of ATT, which provides the read, write, notify and indicate operations on attributes identified by handles and UUIDs.

What is the difference between ATT and GATT?

ATT is the wire protocol of opcodes and handles. GATT defines which attributes form services and characteristics, their declaration UUIDs, and the procedures for discovery, reads, writes and notifications.

Is Bluetooth LE encrypted?

Only after encryption starts on a connection, using a key from pairing or a bond. Advertising is never encrypted unless the device uses Encrypted Advertising Data, and characteristics with no security requirement can be used on unencrypted links. Encrypted links use AES-CCM.

What is the difference between pairing and bonding?

Pairing creates keys for the connection. Bonding stores them so later connections can encrypt without pairing again.

Is Just Works pairing secure?

It gives encryption but no protection against an active man in the middle, and over LE Legacy Pairing none against a passive eavesdropper either. Use it only for low risk data and controlled pairing.

What is the default ATT MTU for BLE?

23 octets on the LE fixed channel. Devices can exchange larger values and both use the smaller one.

What is a resolvable private address?

A random address made of a 24-bit random value and a 24-bit hash of it under the device's IRK. Bonded peers can resolve it; others see an address that changes, recommended at least every 15 minutes.

BLE vs Classic Bluetooth: what is the difference?

Classic (BR/EDR) suits continuous streams such as audio. BLE is designed for low power, intermittent data exposed through GATT. Both live in the Core specification with different link layers and pairing procedures.

How do I check which Bluetooth devices are bonded on Linux?

With BlueZ, run bluetoothctl devices Bonded, then bluetoothctl info with the address for details, and bluetoothctl remove for bonds you no longer want.

Fix it without waiting for upstream

Bluetooth bugs often live outside the radio, in host stacks, in the BLE libraries your mobile and desktop apps import, in the container images of gateways that run BlueZ, and in the firmware and SDKs that device makers build on. Those are dependencies like any other, and the same two gaps apply to them.

Whatever the vulnerability, most of the risk sits in two gaps. The first is the time between a fix being published and that fix actually running in your production builds. The second, and worse, is the time before any fix exists at all, while a maintainer works out a patch and a release schedule. Waiting through both gaps is a habit, not a requirement. Safeguard gives teams three ways to close them.

1. Autonomous remediation: pull requests, not tickets

When a fixed version exists, Safeguard's Griffin models open a tested, policy gated pull request that moves the affected dependency to the safe version. You can run it on one repository or in bulk across every project that carries the vulnerable version. Remediation covers eight categories, including dependencies, licenses, security posture and findings. Reachability analysis ranks the vulnerable code paths your application actually calls first, so the first pull requests you merge are the ones that matter most. Autonomous remediation ships switched off, with every category set to Manual, so your team decides how much runs on its own and what still needs a human approval.

2. Gold Open Source: the safe version in seconds, free

gold.safeguard.sh is free and needs no login. Search any CVE or package to see affected and fixed versions, CVSS, EPSS, CISA KEV status and a recommended safe version, or use the "Am I affected?" checker. The same data is available through a free read API, README status badges and RSS threat feeds. The safeguard-sh/gold-scan-action GitHub Action can fail a build on a known exploited vulnerability, on any known vulnerability, or never, so a version you have just removed cannot quietly come back in next week's merge.

3. Gold Registry: start from components that are already fixed

registry.safeguard.sh provides hardened, drop in replacements for upstream packages and container images. Every Gold artifact is held continuously to zero exploitable critical or high CVEs, zero malware and a completed license check, with SLSA L3 or higher provenance, a Sigstore signature and a public evidence page you can hand to an auditor. An artifact loses its Gold badge if it regresses. Teams can point their own package directory at the registry so hardened equivalents resolve without changing how developers install anything.

When upstream has no fix yet, or will not ship one, Safeguard first works to get the fix accepted upstream. If the issue is severe or upstream will not move, Safeguard builds a fork, fixes the vulnerability there and publishes a hardened Gold build, so you are not stuck on a maintainer's release schedule. You can also request a hardened, compatibility tested build of a specific package. This fork and patch flow is in early access today, so ask which packages it covers before you plan around it.

Your situationWhat to use
A fixed version existsAutonomous remediation opens the upgrade pull request; Gold Open Source confirms the safe version
You need to know today whether you are affectedGold Open Source lookup and "Am I affected?" checker, free and without login
You want vulnerable versions to stop shippingThe Gold scan GitHub Action in CI, plus Safeguard policies and gates
Upstream has no fix yet, or will not ship oneA custom Gold request; fork and patch (early access)
You want to start clean on new projectsPull hardened components and images from Gold Registry

One honest limit: when the vulnerable code lives in a vendor appliance, a hosted service or an operating system runtime you do not build yourself, the fix still has to come from that vendor or distribution. The steps above apply to the open source dependencies and container images you build and ship, which is where most teams carry the largest and least tracked share of their exposure.

See how Safeguard would help

For Bluetooth, that limit is real: controller firmware, a phone's operating system stack and closed vendor SDKs are patched by their makers. What Safeguard covers, all generally available, is the software you build around them: software composition analysis with a full transitive inventory of the Bluetooth libraries your apps and services pull in, SBOM generation and analysis in SPDX and CycloneDX, vulnerability management with EPSS and KEV enrichment and reachability analysis, and container scanning for gateway images that bundle a Bluetooth stack. Safeguard does not monitor radio traffic, pair with devices or inspect Bluetooth links.

These demos show dependency, SBOM and remediation workflows, not Bluetooth traffic analysis. You can download Safeguard and follow the CLI docs to try them on your own projects.

This demo sets up the Safeguard runner on your own machine, approves it with its device code and then scans from the terminal. Pointed at the repository for a companion mobile app, or at the container image of an edge gateway that runs a Bluetooth stack, the same scan lists the Bluetooth related libraries inside with their versions and any known vulnerabilities.

Click through it at your own pace, or open it full screen.

This demo is a real CLI session: install, open the interactive terminal, ask it to fix the lodash CVE in a repository, and watch it read the finding and advisory, ask before each command, move lodash to 4.17.21, run npm install and npm test with approval, and print a summary without pushing anything. The same approve each step flow applies when the dependency to bump is a BLE client library pinned in an app's manifest.

Click through it at your own pace, or open it full screen.

This demo is a real Android session: send work to a computer running the Safeguard CLI, then approve the command on the phone with Allow once, Allow for turn or Deny. It suits the moment you are standing next to the hardware you are testing and want the dependency upgrade on your workstation to wait for your approval.

Click through it at your own pace, or open it full screen.

Quick check

A characteristic's properties show Read and Write. Does that mean any connected client can write to it?

No. Properties list the operations the characteristic supports and are set without regard to security. Whether a given client may write depends on the attribute's permissions, which ATT does not expose. A well configured server answers an unauthorised write with an error such as Insufficient Authentication (0x05) or Insufficient Encryption (0x0F).

Two devices paired with Just Works over LE Legacy Pairing, and nobody was listening at the time. Is the link protected afterwards?

Against eavesdropping, yes: the Core specification says that if pairing happens without an eavesdropper present, all legacy methods provide confidentiality. Against impersonation, no: Just Works gives unauthenticated keys, so the devices never verified each other. And if anyone did capture that pairing, the keys can be derived, which is why LE Secure Connections is preferred.

Sources

Last reviewed: 23 October 2026. The Bluetooth Core Specification and BlueZ options change between releases; check the version your devices and hosts actually run.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.