Advanced levelPremiumbounty: $2500

Android XSS — exported Activity via ContentActivity (POE/Quora real report)

Walkthrough of Android XSS exploitable via an exported Activity intent in POE: how a filter-less ContentActivity leaks the WebView to attacker-controlled sites.

Gorka El BochiMay 11, 202613 min

Stop reading about bugs and start hunting them

No card · free Academy · cancel anytime

Create free account

Quick answer

On Android, an Activity marked exported="true" can be invoked by any installed app via an Intent — with no permissions. If that Activity accepts an html parameter and loads it directly into a WebView with the main domain's context (www.quora.com), you have stored XSS on mobile + access to the native JSBridge + escalation to RCE on Android ≤4.2. Quora paid $2,500 for this in 2016 and the pattern is still valid in modern Android apps (banking, social, productivity). 5 minutes with adb + Drozer reveal whether your target is vulnerable.


1. Refresher: how Android Intents work

Android has 4 component types: Activities, Services, BroadcastReceivers, ContentProviders. Any of them can have android:exported="true" in the AndroidManifest.xml.

xml
<activity
    android:name=".ContentActivity"
    android:exported="true">    <!-- ❌ accesible desde cualquier app -->
</activity>

When exported=true:

  • Any installed app can invoke it with an Intent.
  • It requires no special permissions (unless declared with <permission>).
  • The Intent extras are 100% attacker-controlled.

Why exported=true is sometimes set

  • Deep links (https://target.com/x → opens Activity X).
  • Integrations with other apps (share intent, file picker).
  • Custom URL schemes (myapp://).
  • On Android 12+ it's mandatory to explicitly declare exported=true/false — many devs set it true "for security" without understanding it's the opposite.

2. The real case — Quora Android (2016, $2,500)

Affected activities

xml
<activity android:name="com.quora.android.ContentActivity" android:exported="true"/>
<activity android:name="com.quora.android.ModalContentActivity" android:exported="true"/>
<activity android:name="com.quora.android.ActionBarContentActivity" android:exported="true"/>

All three accepted two Intent extras:

ExtraMeaning
urlReference URL (not validated)
htmlHTML content loaded directly into the WebView

The WebView was loaded with the context of www.quora.com — that is, any injected JS ran with that origin and with access to the native QuoraAndroid JSBridge.

Base payload via ADB

bash
adb shell am start \
  -n com.quora.android/com.quora.android.ActionBarContentActivity \
  -e url 'http://test/test' \
  -e html 'XSS<script>alert(document.domain)</script>'

Result: an alert with www.quora.com → XSS in Quora's authenticated context.


Keep reading the full chain

The remaining part includes the step-by-step PoC, exploitation code and the full chain that led to impact. Available to subscribers.

Free · no account

The checklist I run on every new target

47 checks ordered by cost: first what can get you in trouble, then the cheap stuff, and finally the expensive stuff — which is where the big bounties are. I'll send it to your inbox right now.

Unsubscribe in one click, from any email.

Practice this in a lab

Mobile Android Xss

Solve

Keep learning · free account

Save your progress, unlock advanced payloads and rank your flags.

Create account

Related articles

4,183

hunters training

68

labs from real hacks

2,125

completions

$14,790

paid out for these bugs

6 flags captured this week·Real hacks from HackerOne · YesWeHack · Bugcrowd·No commitment·Free Academy

The community

This isn't a platform with users.It's people breaking the same things you are.

Inside people ask, share what they found and solve together what would block anyone on their own. It's free to join: no account, no plan, no email required.

Join the BBLABS community on Discord
Join the Discord

Free and open. You don't need a BBLABS account to join.