Splunk Enterprise Certified Admin study materials
Splunk Enterprise Certified Admin study resources

Role Mapping Grants More Than Intended

Splunk Enterprise Certified Admin ยท Put your knowledge to work in context.

All case studies

Role Mapping Grants More Than Intended

LDAP is the authentication strategy for a 300-user deployment. Two LDAP groups map to Splunk roles: splunk-ops โ†’ power, and splunk-contractors โ†’ a custom role contractor_ro whose srchIndexesAllowed is orders;cases and whose srchFilter is host=ext-*. A contractor who belongs to exactly one LDAP group reports that the filter does not work: they can search index=_internal and see events from every host in orders. Investigation shows the LDAP strategy's defaultRole is user, and that a previous administrator edited the user role's srchIndexesAllowed to include _internal. A stale role temp_power still exists and is pulled in through importRoles on contractor_ro. SAML is also enabled for the same population, mapping a groups attribute to roles.

1. Why is the contractor's search filter ineffective, and why can they reach `_internal`? Explain the underlying rule.

Read the worked answer

Splunk does not pick one role and use its restrictions. A user's effective permission set is the union of every role they hold, including roles inherited through importRoles.

That produces two separate failures here:

  1. Search filters are combined permissively. srchFilter values from multiple roles are OR'ed, not AND'ed. The contractor holds contractor_ro (filter host=ext-*) plus the defaultRole of user, which carries no meaningful filter. host=ext-* OR (no restriction) returns everything - the more permissive role wins and the restriction silently evaporates. A filter is only a restriction if every role the user holds carries a non-trivial filter.
  2. Index access is additive, and someone edited the user role to include _internal in srchIndexesAllowed. Because defaultRole = user applies to every authenticated account, that one edit gave internal-index visibility to the entire 300-person population, including contractors.

The temp_power role compounds it: contractor_ro imports it, so anyone in the contractor group inherits power-level capabilities and index breadth regardless of what contractor_ro itself says. importRoles is the most common unintended privilege escalation in Splunk role design.

Note also that SAML is enabled for the same users: if the SAML groups attribute maps them into additional roles, those roles union in as well.

2. How do you determine what a specific user can actually do, rather than reasoning from the role definitions on paper?

Read the worked answer

Query the effective state through REST rather than reading the role pages.

  1. Effective roles for the account (this returns assigned and inherited roles):
| rest /services/authentication/users splunk_server=local
| search title="jdoe"
| fields title roles realname

If roles lists something unexpected, you have found your escalation path before touching a search.

  1. The permissions behind those roles:
| rest /services/authorization/roles splunk_server=local
| search title IN (contractor_ro, user, temp_power)
| table title srchIndexesAllowed srchIndexesDefault srchFilter imported_roles
  1. Empirical test as the user, which catches what the config view misses: log in as the contractor (or use a test account in the same group) and run
index=_internal | stats count
index=orders | stats count by host

If _internal returns rows, or the orders results show hosts outside ext-*, the union is confirmed.

  1. Check the identity source too. Re-run the same check after an LDAP logon vs a SAML logon, because the groups claim and the LDAP group mapping can produce different role sets for the same person. Never assume the two authentication paths are equivalent - the user will use whichever one is offered first.

3. What is the target design here, so contractors stay constrained while LDAP and SAML coexist?

Read the worked answer

Rebuild around two principles: constrain by index, and never let an unconstrained role attach to a constrained user.

  1. Never rely on srchFilter as the primary boundary. Because filters OR together across roles, a filter is one inheritance change away from being void, and it also taxes search performance. Use it only as a refinement for users who hold exactly one role. The real boundary should be srchIndexesAllowed: contractors get exactly orders;cases, nothing more.
  2. Fix defaultRole. Setting defaultRole = user for every authenticated account is the root cause of the _internal exposure. Either revert the user role's srchIndexesAllowed to a sane baseline and grant _internal only via an admin role, or set defaultRole to a purpose-built minimal role.
  3. Break the inheritance. Remove importRoles = temp_power from contractor_ro, and delete temp_power once you have confirmed no active user depends on it. Audit every role for importRoles and for srchIndexesAllowed containing *, _internal, _audit or _introspection.
  4. Make the two identity paths deterministic. Give LDAP and SAML non-overlapping role namespaces, and make the SAML groups attribute map contractors to the constrained role only. Test both logon paths, because a user who can authenticate two ways gets the union of both role sets.
  5. Detect drift. Schedule a saved search over /services/authorization/roles that alerts when any role holding _internal is granted to a user outside the admin group - this class of misconfiguration is introduced by well-meaning admins, not attackers, so monitoring is the only durable control.