Android notifications do not properly handle some Unicode characters, leading to inconsistencies between what is displayed and what is used by the automatic Open Link suggestions. This may trick users into opening a different link from the one shown in the notification. The misbehaviour can be exploited for phishing or to trigger app links and deep links.
Background
If you regularly use an Android device, you may have noticed that notifications often include suggestions based on their content. This is particularly common—and useful—when the notifications come from messaging apps, where the system automatically suggests actions such as quick replies or opening a link contained into the message text.
In this post, I focus on the Open Link suggestion, a button that lets users open links (automatically) extracted from a notification. It is important to clarify from the beginning that developers do not explicitly implement this feature; it is provided automatically by Android’s notification system. In this post, I will show examples using WhatsApp, Telegram, Instagram, Discord, and Slack.
The Idea
What if someone could make the Open Link suggestion open a different link from the one displayed in the notification?
Let’s take, for example, the following notification:
As shown in the screenshot, the notification displays a link to amazon.com and, as expected, includes an Open Link suggestion. But… are we sure the link that opens is actually amazon.com? Unfortunately, no. In fact, tapping Open Link on that specific notification opens zon.com (empty at the time of writing).
How is this possible?
The issue lies in the way Android handles (some) Unicode characters in notifications. Certain characters—including some invisible ones—are not filtered or processed consistently, causing a mismatch between what is rendered and what the suggestion engine parses.
In the example above, the actual message text was:
ama[]zon.com
where [] represents an invisible Unicode character (U+200B, zero width space). The notification renders ama[]zon.com, including the hidden character. However, the suggestion engine treats that character as a separator, seeing ama and zon.com as two separate words. It then extracts zon.com as the link to open, so pressing Open Link opens zon.com.
A clearer case is:
where ൘ (U+0D58) is a visible Unicode character. The notification displays ama൘zon.com, but the suggestion opens zon.com. Obviously, the misbehaviour is more interesting when the character is invisible, as in the original example.
It is interesting to note that, in some cases, Unicode characters actually trigger more correct behavior. For example, consider the case shown in the following screenshot.
In this notification, each "a" in amazon.com is in fact a Cyrillic small letter a (U+0430) rather than the standard Latin "a". This is a common technique used in phishing attacks, where visually similar characters (known as homoglyphs) are substituted to deceive users into clicking links that appear legitimate but are not. In this particular case, the notification simply does not show the Open Link button.
Consequences
Opening Different Links
This misbehaviour can be trivially exploited to deceive users into opening a different link from the one shown in the notification. The main limitation is that the opened link must be a substring of the displayed link, but that hardly prevents an attacker from crafting persuasive payloads.
Consider another toy example.
Here, the Open Link suggestion opens polimi.it. Indeed, the message contains actually the text www.polimi.it[]alia.[]google.[]com, where [] represents the usual invisible character (U+200B, zero width space). These characters are used to split the link into meaningful segments so that polimi.it is matched as a link, while other parts of the text containing potential link patterns are not.
One more.
The notification displays the full link, yet the Open Link suggestion silently opens tinyurl.com/2bc33y5s, which redirects to my website. The actual message text is:
Here, the invisible character (U+200B, zero width space) is used to prevent wired.com from being matched as a link, ensuring that only the desired URL (tinyurl.com/2bc33y5s) is detected and suggested.
With more imagination, an attacker could craft even sneakier notifications.
App Links and Deep Links
The same misbehavior can deceive users into triggering app or deep links while they believe they are simply opening a regular website. For example:
and the Open Link suggestion silently targets wa.me/1234567890?text=provola, which launches WhatsApp with a pre-filled message.
This happens because wa.me is registered by WhatsApp. When tapped, it invokes a deep link inside the app that opens a specific view — in this case, a chat window with the number 1234567890 and the message provola. These links are often used for legitimate app integrations but can also be abused to trigger unintended app behavior (see below).
Combining with URL-shortener
As shown in the previous example, if a link can be handled by an installed app, the Open Link suggestion in the notification displays the app's icon instead of the default browser icon. This makes the attack more noticeable to users. Furthermore, the Android notification system typically does not match custom URI schemes (i.e., schemes other than http or https), which are commonly used by app links.
To make the attack less detectable and support any type of URI scheme, attackers can use a URL shortener.
while Open Link opens tinyurl.com/cardarella, which redirects to:
whatsapp://call-phone-number?phone=1234567890
prompting a whatsapp call to that number. In this case as well, in the tested WhatsApp version, the call requires user confirmation—this is an intentionally harmless example used for demonstration purposes.
Ok, but what can I do?
In well-designed apps, deep links that trigger actions—like sending a message, starting a call, or opening a specific screen—should always ask for user confirmation. But in the real world? That’s not always the case.
Sometimes, due to poor implementation, apps skip this crucial step, assuming that any incoming link comes from a trusted user interaction. The result? Deep links can silently perform actions without the user even realizing it. I recently encountered one such misconfigured deep link in an official Google app—no confirmation, no warning, just straight to execution (don't worry, I reported it through the proper disclosure channels). In this context, the misbehavior described here can serve as a potential entry point for deep-link exploitation.
Tests
The misbehaviour was tested on the following applications:
WhatsApp
Telegram
Instagram
Discord
Slack
Some invisible characters fail in certain apps. For example, U+200B (zero width space) works on WhatsApp but not on Telegram, while U+2065 (invisible plus) succeeds on Telegram. This is likely due to internal filtering mechanisms implemented either within the app itself or on their backend servers, which prevent the storage or transmission of certain characters.
To bypass app-specific filters and validate my findings, I built a custom app capable of sending notifications with arbitrary Unicode content. This confirmed the initial observations and revealed many characters that can trigger the misbehaviour.
Devices tested
Google Pixel 9 Pro XL (Android 16 BP2A.250605.031.A2 and older)
Google Pixel 9 Pro (Android 15 BP1A.250305.020.A2 and older)
I reported this issue to Google on 11 March 2025 through the Google Bug Hunter program (Android & Devices VRP). Below, I will share their response without any further comments.
On 26 March 2025 Google replied:
After waiting more than a couple of months for a fix on my Pixel 9 Pro XL, I asked for an update on 6 June 2025. Google replied on 7 June 2025:
I have informed the team of my intention to publish this post, and they had the opportunity to read it in advance.
Other Mobile Systems
Just as a reference, I’ll briefly discuss the behavior on iOS/iPadOS—practically the only other major mobile operating system.
As shown in the screenshot, iOS/iPadOS exhibits the same general behavior: it splits the URL at the invisible Unicode character. However, there is one huge difference. In this case, the matching part of the link is styled with a different color and underline (typical of URLs), making it trivial for the user to spot the misbehavior.
Don't Trust the Open Link Button in Android Notifications
June 11, 2025
Cover image: @Frank01001
TL;DR
Android notifications do not properly handle some Unicode characters, leading to inconsistencies between what is displayed and what is used by the automatic Open Link suggestions. This may trick users into opening a different link from the one shown in the notification. The misbehaviour can be exploited for phishing or to trigger app links and deep links.
Background
If you regularly use an Android device, you may have noticed that notifications often include suggestions based on their content. This is particularly common—and useful—when the notifications come from messaging apps, where the system automatically suggests actions such as quick replies or opening a link contained into the message text.

In this post, I focus on the Open Link suggestion, a button that lets users open links (automatically) extracted from a notification. It is important to clarify from the beginning that developers do not explicitly implement this feature; it is provided automatically by Android’s notification system. In this post, I will show examples using WhatsApp, Telegram, Instagram, Discord, and Slack.
The Idea
What if someone could make the Open Link suggestion open a different link from the one displayed in the notification?
Let’s take, for example, the following notification:

As shown in the screenshot, the notification displays a link to

amazon.com
and, as expected, includes an Open Link suggestion. But… are we sure the link that opens is actuallyamazon.com
? Unfortunately, no. In fact, tapping Open Link on that specific notification openszon.com
(empty at the time of writing).How is this possible?
The issue lies in the way Android handles (some) Unicode characters in notifications. Certain characters—including some invisible ones—are not filtered or processed consistently, causing a mismatch between what is rendered and what the suggestion engine parses.
In the example above, the actual message text was:
where
[]
represents an invisible Unicode character (U+200B, zero width space). The notification rendersama[]zon.com
, including the hidden character. However, the suggestion engine treats that character as a separator, seeingama
andzon.com
as two separate words. It then extractszon.com
as the link to open, so pressing Open Link openszon.com
.A clearer case is:

where
൘
(U+0D58) is a visible Unicode character. The notification displaysama൘zon.com
, but the suggestion openszon.com
. Obviously, the misbehaviour is more interesting when the character is invisible, as in the original example.It is interesting to note that, in some cases, Unicode characters actually trigger more correct behavior. For example, consider the case shown in the following screenshot.

In this notification, each "a" in
amazon.com
is in fact a Cyrillic small letter a (U+0430
) rather than the standard Latin "a". This is a common technique used in phishing attacks, where visually similar characters (known as homoglyphs) are substituted to deceive users into clicking links that appear legitimate but are not. In this particular case, the notification simply does not show the Open Link button.Consequences
Opening Different Links
This misbehaviour can be trivially exploited to deceive users into opening a different link from the one shown in the notification. The main limitation is that the opened link must be a substring of the displayed link, but that hardly prevents an attacker from crafting persuasive payloads.
Consider another toy example.

Here, the Open Link suggestion opens
polimi.it
. Indeed, the message contains actually the textwww.polimi.it[]alia.[]google.[]com
, where[]
represents the usual invisible character (U+200B, zero width space). These characters are used to split the link into meaningful segments so thatpolimi.it
is matched as a link, while other parts of the text containing potential link patterns are not.One more.

The notification displays the full link, yet the Open Link suggestion silently opens
tinyurl.com/2bc33y5s
, which redirects to my website. The actual message text is:Here, the invisible character (U+200B, zero width space) is used to prevent
wired.com
from being matched as a link, ensuring that only the desired URL (tinyurl.com/2bc33y5s
) is detected and suggested.With more imagination, an attacker could craft even sneakier notifications.
App Links and Deep Links
The same misbehavior can deceive users into triggering app or deep links while they believe they are simply opening a regular website. For example:

The actual text is
and the Open Link suggestion silently targets
wa.me/1234567890?text=provola
, which launches WhatsApp with a pre-filled message.This happens because
wa.me
is registered by WhatsApp. When tapped, it invokes a deep link inside the app that opens a specific view — in this case, a chat window with the number1234567890
and the messageprovola
. These links are often used for legitimate app integrations but can also be abused to trigger unintended app behavior (see below).Combining with URL-shortener
As shown in the previous example, if a link can be handled by an installed app, the Open Link suggestion in the notification displays the app's icon instead of the default browser icon. This makes the attack more noticeable to users. Furthermore, the Android notification system typically does not match custom URI schemes (i.e., schemes other than
http
orhttps
), which are commonly used by app links.To make the attack less detectable and support any type of URI scheme, attackers can use a URL shortener.

The actual notification text is the following:
while Open Link opens
tinyurl.com/cardarella
, which redirects to:prompting a whatsapp call to that number. In this case as well, in the tested WhatsApp version, the call requires user confirmation—this is an intentionally harmless example used for demonstration purposes.
Ok, but what can I do?
In well-designed apps, deep links that trigger actions—like sending a message, starting a call, or opening a specific screen—should always ask for user confirmation. But in the real world? That’s not always the case.
Sometimes, due to poor implementation, apps skip this crucial step, assuming that any incoming link comes from a trusted user interaction. The result? Deep links can silently perform actions without the user even realizing it. I recently encountered one such misconfigured deep link in an official Google app—no confirmation, no warning, just straight to execution (don't worry, I reported it through the proper disclosure channels). In this context, the misbehavior described here can serve as a potential entry point for deep-link exploitation.
Tests
The misbehaviour was tested on the following applications:
Some invisible characters fail in certain apps. For example, U+200B (zero width space) works on WhatsApp but not on Telegram, while U+2065 (invisible plus) succeeds on Telegram. This is likely due to internal filtering mechanisms implemented either within the app itself or on their backend servers, which prevent the storage or transmission of certain characters.
To bypass app-specific filters and validate my findings, I built a custom app capable of sending notifications with arbitrary Unicode content. This confirmed the initial observations and revealed many characters that can trigger the misbehaviour.
Devices tested
Video
Disclosure
I reported this issue to Google on 11 March 2025 through the Google Bug Hunter program (Android & Devices VRP). Below, I will share their response without any further comments.
On 26 March 2025 Google replied:

After waiting more than a couple of months for a fix on my Pixel 9 Pro XL, I asked for an update on 6 June 2025. Google replied on 7 June 2025:

I have informed the team of my intention to publish this post, and they had the opportunity to read it in advance.
Other Mobile Systems
Just as a reference, I’ll briefly discuss the behavior on iOS/iPadOS—practically the only other major mobile operating system.

As shown in the screenshot, iOS/iPadOS exhibits the same general behavior: it splits the URL at the invisible Unicode character. However, there is one huge difference. In this case, the matching part of the link is styled with a different color and underline (typical of URLs), making it trivial for the user to spot the misbehavior.