Skip to content

nimble/host: inherit characteristic security requirements in CCCD#2259

Open
gmarull wants to merge 1 commit into
apache:masterfrom
teslabs:cccd-sec
Open

nimble/host: inherit characteristic security requirements in CCCD#2259
gmarull wants to merge 1 commit into
apache:masterfrom
teslabs:cccd-sec

Conversation

@gmarull

@gmarull gmarull commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

The CCCD was registered with plain read/write permissions regardless of the security declared on its characteristic, so any unencrypted client could subscribe and receive an otherwise protected value via notifications/indications, bypassing its protection.

The Core Specification leaves CCCD write permissions to the implementation and anticipates gating them (Vol 3, Part G, 3.3.3.3; Vol 3, Part F, 3.2.5). Zephyr already enforces this: the CCC carries its own security permissions, and the value's read security is checked in the notify/indicate send path. NimBLE auto-generates the CCCD with no per-descriptor permission API, so inherit the characteristic's security requirements to achieve the same protection.

Require for the CCCD write the union of the characteristic's read and write encryption/authentication flags, derived via ble_gatts_att_flags_from_chr_flags to keep a single mapping point, and propagate min_key_size as well. Authorization flags are deliberately not inherited: ble_att_svr_check_perms does not enforce authorization (left to the access callback, which for the CCCD is stack-internal), and the flag alone would activate the min_key_size check, rejecting every CCCD write on an unencrypted link. CCCD reads remain unprotected, per Vol 3, Part G, 3.3.3.3.

@sjanc sjanc left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is reasonable approach (but please fix style reported)

The CCCD was registered with plain read/write permissions regardless of
the security declared on its characteristic, so any unencrypted client
could subscribe and receive an otherwise protected value via
notifications/indications, bypassing its protection.

The Core Specification leaves CCCD write permissions to the
implementation and anticipates gating them (Vol 3, Part G, 3.3.3.3;
Vol 3, Part F, 3.2.5). Zephyr already enforces this: the CCC carries
its own security permissions, and the value's read security is checked
in the notify/indicate send path. NimBLE auto-generates the CCCD with
no per-descriptor permission API, so inherit the characteristic's
security requirements to achieve the same protection.

Require for the CCCD write the union of the characteristic's read and
write encryption/authentication flags, derived via
ble_gatts_att_flags_from_chr_flags to keep a single mapping point, and
propagate min_key_size as well. Authorization flags are deliberately
not inherited: ble_att_svr_check_perms does not enforce authorization
(left to the access callback, which for the CCCD is stack-internal),
and the flag alone would activate the min_key_size check, rejecting
every CCCD write on an unencrypted link. CCCD reads remain
unprotected, per Vol 3, Part G, 3.3.3.3.

Signed-off-by: Gerard Marull-Paretas <gerard@teslabs.com>
@gmarull

gmarull commented Jul 8, 2026

Copy link
Copy Markdown
Contributor Author

I think this is reasonable approach (but please fix style reported)

Thanks, fixed style

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants