_security/user/_has_privileges may appear to return false for some privilges when the expectation is to return true #106926
Labels
>bug
:Security/Security
Security issues without another label
Team:Security
Meta label for security team
There is an expectation that privileges generally adhere to some hierarchy w.r.t. to their naming.
For example, there is an expectation that if you have permissions to the cluster level privilege
monitor
then you should also have privileges tomonitor_enrich
. This expectation holds for checking action the action names, but does not always hold when checking with_has_privileges
.For example, the monitor privilege deconstructed is effectively
cluster:monitor/*
, so when checking action namecluster:monitor/xpack/enrich/stats
orcluster:monitor/xpack/enrich/esql/resolve_policy
always matches expectations and returnstrue
since we effectively resolvecluster:monitor/xpack/enrich/stats
againstcluster:monitor/*
and it passes. Technically, this is implemented with Lucene automatons with pseudo code such as:So the exceptions for the hierarchy in the naming conventions holds true when checking action names (the primary use).
However, you would expect the same hierarchy w.r.t. naming to still hold true when using the
_has_privileges
API. It would be expected, that if you havemonitor
cluster permission and ask the_has_privileges
API if you have privileges tomonitor_enrich
, you would expect the result to betrue
. But, it is not. The answer is false.The
_has_privileges
works slightly differently than when checking action names._has_privileges
doesn't resolve static strings against Automatons (nor can it). In the_has_privileges
there are 2 Automatons, not one. One automaton representsmonitor
and another representsmonitor_enrich
. So, if your role allows you permissions to themonitor
cluster privilege and you check if you havemonitor_enrich
via_has_privileges
the implementation looks to see ifmonitor_enrich
is a subset ofmonitor
. So the psuedo code isThis may return true or it may return false. It depends on exactly what permissions make up the Automatons. It will return
true
under the following conditions:monitor
Automaton representscluster:monitor/*
monitor_enrich
Automaton representscluster:monitor/xpack/enrich/*
In the above case, per the view of the Automaton,
cluster:monitor/xpack/enrich/*
is a subset ofcluster:monitor/*
The problem arises when the automaton represents multiple permissions and one or more permission is not a direct subset of the first. The following condition will return
false
monitor
Automaton representscluster:monitor/*
monitor_enrich
Automaton representscluster:monitor/xpack/enrich/*
ANDcluster:admin/xpack/enrich/get
In the above case, per the view of the Automaton,
cluster:monitor/xpack/enrich/*
ANDcluster:admin/xpack/enrich/get
is NOT a subset ofcluster:monitor/*
From the Automaton perceptive this correct behavior. However, from the expectations of permissions this is arguably a bug and most certainly defies usage expectations.
The example chosen here is a real example, but there are cases where the expectations of hierarchy w.r.t. to their naming don't roll up correctly when using the
_has_privileges
API .Steps to Reproduce
To reproduce:
create a role like this:
Assign that to a user, then with that user call
_security/user/_has_privileges
withNote the
false
response:Logs (if relevant)
No response
The text was updated successfully, but these errors were encountered: