← Back to Wiki
Security / Access Control

UniFi RBAC Gap: a Limited Admin Can Still Read Full Site Settings

A social-engineering attempt that did not work is still a good reason to audit everything else. An unrelated vishing call triggered a precautionary sweep across a home network's infrastructure. It turned up an automation API key with far more access than it needed, and a role downgrade that looked like a fix and was not a complete one.

Share on X

Why an unrelated phone call led to auditing a router

The call itself never got anywhere. It targeted a Google account, not self-hosted infrastructure. But a caller who has done real reconnaissance is a signal worth taking seriously, not a one-off. The reasonable response is not "nothing happened, move on". It is a precautionary pass across everything that account, or an account like it, could plausibly pivot toward. Source control, password managers, cloud accounts, and the network controller itself.

What the audit found

Buried in that sweep was a UniFi Network API key created months earlier for a read-only documentation-sync job. It was backed by an admin account still set to Super Admin. Nothing had ever needed that level of access. The automation only listed sites, devices and clients. It had never been revisited since the day it was created.

The obvious fix is dropping that account to a restricted role, and UniFi supports exactly that. A custom viewer role, with both the network and admin permission scopes set to "View Only", already existed and was in use by a separate, correctly scoped automation account on the same controller. Applying the same role to the over-privileged key looked like a clean, complete fix.

The part that didn't actually get fixed

BE WARNED: the role change did not close the real gap. UniFi's granular admin roles, Super Admin against Viewer with separate Network and Admin permission scopes, govern the modern Integrations API and most of the Network app's own UI. They do not appear to govern one legacy endpoint. GET /proxy/network/api/s/<site>/rest/account still returned full account records, including a plaintext password field, from a key backed by an account explicitly downgraded to view-only. Same request, same response, before and after the role change.

I confirmed that directly. The same API key, on the same credential, hit that endpoint before and after the role downgrade and got byte-for-byte the same sensitive fields back both times. If your only verification step is "I changed the role, so it is fixed", you walk away from an incident like this with a false sense of closure.

What to actually do about it

Report platform gaps like this upstream. A permission model that silently does not apply to one endpoint is a real bug, not a configuration mistake. File it with the vendor so it gets fixed for everyone, rather than worked around locally.