Skip to content

Cve 2026 23866 Finding A Whatsapp Nday

numb3rs.re • October 6, 2026

On May 1 2026, CVE-2026-23866 was published, the vulnerability reportedly allows a malicious attacker to force a victim into loading an arbitrary URL and thus leaking important information (headers, ip address, …). It’s a low grade vulnerability but I’ve never worked on Whatsapp so I figured it’d be interesting to take a look at it.

The only informations I will be using are those publicly available on the NIST website . It describes the vulnerable version to be 2.25.8.0 < 2.26.15.72 on iOS and 2.25.8.0 < 2.26.7.10 on Android. The description of the vulnerability is the following: Incomplete validation of AI rich response messages for Instagram Reels in WhatsApp [...] could have allowed a user to trigger processing of media content from an arbitrary URL on another user’s device [...] . I’m more familiar with the iOS environment so that’s what I’ll be working on. I’ll be using Whatsapp iOS version 25.9.72 for my test and IDA Pro for decompiling.

Luckily and surprisingly, the binaries shipped with WhatsApp aren’t that big so it doesn’t take too long to decompile.

Because on this blog we only allow top-tier hacking and I don’t play around, I’m bringing the big guns right off the bat and thus I will be using grep on the unzipped iPA to find occurrence of AiRich (yes, yes this is top-tier hacking I swear):

This isn’t too bad to begin with.. So I started reverse-engineering SharedModules .

We have quite a lot of functions containing AiRich , and, SharedModules seems to be dedicated to parsing the various protocol messages.

We know that we are looking for processing of media content that will lead to loading an arbitrary url. We can assume that the application tries to load a video (makes sense for an Instagram Reels ) and doesn’t control the validity of the link. That’s why the class WAPBAIRichResponseMessage_AIRichResponseContentItemsMetadata_AIRichResponseContentItemMetadata caught my eye. An AI Rich response that contains fields ? Be my guest.

We also have this function that seems to be extracting the submessage field from a protobuf message.

Since SharedModules doesn’t seem to be dedicated to the logic of Whatsapp, I’m switching to the main Whatsapp binary in IDA.

Using the protobuf definition accessible here :

I crossed-ref the class containing metadata and got the following function:

Thank you Meta for compiling with the -O1 flag, this makes the experience very unpleasing!

I also found this stub that stores the videoUrl in an instance of RichResponseReelItem .

Let’s not stop halfway through and let’s keep X-Refing! We now need to find the function that loads one of the urls.

Here I got kind of stuck because I have no intentions of debugging dynamically and it’s not possible to diff the binaries because of the compiler’s optimizations. I then went back to a hacker’s best tool: guessing.

Several hours of guessing and wading later (because just using Frida would be too much, right), I finally found this function which consumes the videoUrl field:

And if we cross-ref that function, we can find this Objective-C function:

So we got this first sink that is called when we clink on the message - bear in mind the link opened is attacker controlled. However, this sink needs user interaction which isn’t the case for the CVE we’re working on.

Finding the other sink is like finding a needle in a haystack - I did try to debug dynamically but sadly the Whatsapp version is too old and the backend blocks registration on those version. I’m guessing I could bypass this by modifying the version in the IPA, re-signing and everything but it’s not what i’m interested in right now.

I did try to send the message using whatsmeow with this snippet:

Here is what it displays on recent versions:

When we click on the reel, we are redirected on the provided videoUrl in Safari. It’s not possible to really see how it would display on old versions and I really don’t want to have to dig in the Swift UI components of Whatsapp, the fact the it compiles inline is really annoying because it makes it way harder to decompile - IDA doesn’t load the stubs to load the arguments and thus you have to dig in each stub to know which argument goes where.

Maybe a plugin such as this would be a good solution to “bypass” the compiler’s optimizations but this isn’t what this blog post is .

In conclusion, we were able to prove a 1-click path but not a 0-click one.

Even though I couldn’t find the CVE’s automatic media-processing sink, we saw that Whatsapp does extract an URL from a user controlled protobuf and we confirmed that this URL is then loaded without making sure it points to a trusted destination. I’m pretty sure this represents a vuln in itself, this user seem to have been paid a bounty for finding this type of vulnerability. I’m not sure how the URLs appear on the UI but if they don’t display it and clicking on the message is sufficient for loading a user controlled URL, this could already be considered a vuln. This is not the sink described by CVE-2026-23866, since the path I found requires a user tap. I did not reproduce the vulnerable automatic media-processing path, so identifying that second consumer remains future work. To find our correct stub, I can think of several different options:

Hardcode a more recent Whatsapp version in the binary to bypass the backend check (i’m not familiar with Whatsapp internals, i’m not sure that’d work). I know that the application has also a set expiration date and we would also have to change the date of the phone.

Write and import a custom .dylib in Whatsapp to force it to load a custom message (in this case a RichResponseMessage ).

Anyway, this was my first time writing a post on mobile VR, hope it was interesting. If you have any questions - or think that I missed something, you can reach out to me on discord @ numb3rss.

Extracted Entities

Companies (1)

Tools (2)