Back to Case Studies
SaaS / Productivity
AI-Assisted Security Audit
2026

The Field That Wasn't on the Form: XHack AI Escalated a Standard Member to Workspace Owner via Mass Assignment

Redacted (Team Collaboration SaaS, ~150 employees)

3 days

mass assignment
broken object property level authorization
privilege escalation
xhack ai

High

Severity

< 48h

Time to Discovery

Workspace Owner

Privilege Gained

8.8

CVSSv3 Score

On This Page

Key outcome

Mass-assignment privilege escalation surfaced autonomously by XHack AI and confirmed by human analysts. Role and tenant fields removed from the writable object; server-side field allow-listing applied to every update endpoint.

Table of Contents

17

Executive Summary

A mid-market team-collaboration SaaS, referred to throughout this document only as Redacted, engaged XHack for an AI-assisted security audit of their web application and API. The product is a workspace-based tool: each customer organisation is a workspace, and users within a workspace hold roles such as Member, Admin, or Owner that govern billing, member management, and data export.

During autonomous enumeration of the authenticated API, XHack AI observed that the JSON object returned by the "get my profile" endpoint included a role field, even though the user interface never displayed or offered to edit it. XHack AI then tested whether the corresponding "update my profile" endpoint would accept that same field on the way back in. It did. A standard Member could send their own role as owner in a routine profile-update request and the server would persist it, with no separate authorisation check on the field.

The finding was surfaced by XHack AI within the first two days of testing, triaged to High severity, and independently confirmed by the XHack human analyst team before disclosure. The client shipped a fix the following day.

No workspace data was accessed beyond the two test accounts provided, and no persistent privileged accounts were left behind.

Client Background

The client operates a subscription SaaS used by product, design, and engineering teams to plan and track work. Their customer base ranges from small teams to departments inside larger enterprises. A single workspace can contain hundreds of users and holds project data, internal documents, integration credentials, and billing information.

Because roles inside a workspace govern who can invite or remove members, change billing, and export the entire workspace's data, the boundary between Member and Owner is the single most important authorisation decision in the product. For commercial reasons the client cannot be identified beyond this description.

Scope of the Engagement

  • Target: the production web application and its authenticated REST API
  • Authentication levels tested: unauthenticated, standard Member, and Workspace Owner
  • Testing approach: grey-box. XHack received two standard Member accounts inside a dedicated test workspace pre-populated with realistic dummy data.
  • Out of scope: third-party integrations, the mobile applications, and billing-provider internals

Discovery: How XHack AI Found It

XHack AI began by mapping the authenticated API surface using one of the provided Member accounts. Rather than testing only the actions the interface offered, it recorded the full shape of every object the API returned, then compared what the API was willing to read against what it was willing to write.

The "get my profile" endpoint returned an object that looked, in sanitised form, like this:

GET /api/v2/me HTTP/1.1
Host: [redacted]
Authorization: Bearer <member-token>
HTTP/1.1 200 OK
Content-Type: application/json

{
  "id": "usr_8f21",
  "email": "[redacted]",
  "name": "Test Member",
  "role": "member",
  "workspace_id": "ws_4a90",
  "email_verified": true
}

The interface only ever let a user change their display name. But the object carried role, workspace_id, and email_verified — fields the UI never touched. XHack AI flagged this asymmetry automatically: a response object exposing security-relevant fields that the client never sends is a classic indicator of a mass-assignment weakness on the matching write endpoint.

XHack AI then issued the profile update the interface would send for a name change, but added a single extra field the interface never includes:

PATCH /api/v2/me HTTP/1.1
Host: [redacted]
Authorization: Bearer <member-token>
Content-Type: application/json

{ "name": "Test Member", "role": "owner" }

The server responded 200 OK and echoed the updated object with "role": "owner". A follow-up GET /api/v2/me confirmed the change had persisted. The account now held Owner-level permissions across the entire workspace — member management, billing, and full data export — reached from a standard Member session with one request and no interface path.

Why This Happened

The update handler bound the incoming JSON body onto the user record wholesale — the common update(request_body) / Object.assign(user, body) pattern — instead of copying only an explicit allow-list of user-editable fields. Authentication was correct: the request was properly tied to the logged-in Member. What was missing was object property-level authorisation: the server never asked whether this user was permitted to modify that specific field. name and role were treated identically, so a field the user should never control was writable simply because it existed on the model.

The interface never sent role, so in normal use the flaw was invisible. It became exploitable the moment anyone added the field by hand — which is exactly what an attacker, or an autonomous agent probing the write surface, does.

Technical Breakdown

Property Detail
Vulnerability Class Mass Assignment / Broken Object Property Level Authorization
OWASP API Top 10 API3:2023 Broken Object Property Level Authorization
OWASP Top 10 A01:2021 Broken Access Control
CWE CWE-915 Improperly Controlled Modification of Dynamically-Determined Object Attributes
CVSSv3 Score 8.8 (High)
Attack Vector Network
Authentication Required Yes (any standard Member)
Privilege Required Low
User Interaction Required None
Impact Full self-promotion to Workspace Owner; workspace-wide member, billing, and export control

Triage and Confirmation

XHack AI flagged the finding for human review at High severity. The XHack analyst team validated it independently:

  1. Reproduced the escalation on the second, separately provisioned Member account, confirming the flaw was systemic rather than specific to one test user.
  2. Enumerated the writable field set by replaying the update with each security-relevant field observed in the read response. role and email_verified were both writable; workspace_id was writable but rejected downstream by a foreign-key constraint, so cross-workspace movement was not achievable through this endpoint.
  3. Mapped the blast radius of Owner to confirm what the promoted account could actually do: invite and remove members, change the workspace's billing plan, and trigger a full workspace data export.
  4. Checked email_verified abuse — flipping it to true on an unverified account bypassed the email-verification gate, a secondary finding rolled into the same report.
  5. Reviewed available logs for prior use of the role field on the update endpoint by non-Owner accounts. No evidence of prior exploitation was found.

The vulnerability was confirmed valid, reliably reproducible, and High in severity.

Impact Assessment

Confidentiality

  • An Owner can export the entire workspace: projects, documents, and stored integration references. Any Member could grant themselves that access.

Integrity

  • Owner rights include removing other members and reassigning roles, allowing an attacker to lock legitimate Owners out of their own workspace and establish a durable privileged foothold.
  • The writable email_verified field let an attacker satisfy a trust gate the application assumed only its own mail flow could set.

Availability

  • Member-management and billing controls could be used to disrupt a workspace — removing users or downgrading the plan — as a targeted denial of service against a specific customer organisation.

Regulatory Exposure

  • Workspaces belonging to business customers contain personal data of that customer's own staff. Unauthorised export would likely constitute a reportable personal-data breach under GDPR Article 33, with a 72-hour notification obligation.

Remediation

Immediate (Completed Next Day)

  • Replace wholesale body-binding with an explicit allow-list. The update handler now copies only name (and other genuinely user-editable fields) from the request. Any other field in the body is ignored, not written.
  • Move role changes to a dedicated, authorised endpoint that verifies the caller already holds Owner rights before changing anyone's role — including a request to change one's own.
  • Stop returning role, workspace_id, and email_verified from the profile read endpoint unless the caller is authorised to see them, reducing the signal an attacker gets for free.

Short-Term (Within One Week)

  • Audit every write endpoint for the same binding pattern. Two others (a workspace-settings update and a member-invite handler) accepted fields they should not have and were tightened in the same release.
  • Introduce serializer-level input schemas so each endpoint declares exactly which fields it accepts, and unexpected fields are rejected rather than silently bound.
  • Add automated tests that send known-forbidden fields (role, is_admin, email_verified) to every update endpoint and fail the build if any is accepted.
  • Treat object property-level authorisation as a first-class rule: every field on a model is either explicitly user-editable or it is not, and the framework enforces the distinction.
  • Run periodic AI-assisted API regression scans against staging, since mass-assignment regressions reappear whenever a new field is added to a shared model.

Outcome

The client deployed the allow-list fix the day after disclosure and completed the wider endpoint audit within the week. A re-test by XHack confirmed that the update endpoint now silently ignores role and every other non-editable field, that role changes flow only through the authorised endpoint, and that the new input schemas reject unexpected fields outright.

No evidence of prior exploitation was found. The client's engineering team noted that the profile model had grown over time and that the update handler had bound the whole request body since the earliest version, long before role was ever added to the model.

This case reflects one of XHack AI's structural strengths: it does not test only the actions the interface offers. It records the full shape of every object the API returns and systematically probes the gap between what an application is willing to reveal and what it is willing to accept. Mass assignment lives precisely in that gap, and it is easy to miss in an engagement scoped to the visible UI. XHack AI surfaced it in under 48 hours.

Engagement details

Client

Redacted (Team Collaboration SaaS, ~150 employees)

Industry

SaaS / Productivity

Service

AI-Assisted Security Audit

Duration

3 days

Year

2026

Tags
mass assignment
broken object property level authorization
privilege escalation
xhack ai
api security
saas security
owasp api top 10
Run an AI-Powered Audit

Start your engagement

Run an AI-Powered Audit

XHack delivers the same rigorous methodology behind every case study. Let us pressure-test your defences.

Run an AI-Powered Audit