CVE-2020-6506: uXSS in Android WebView
About
Π£ΡΠ·Π²ΠΈΠΌΠΎΡΡΡ Π·Π°ΡΡΠ°Π³ΠΈΠ²Π°Π΅Ρ Π²Π΅Π½Π΄ΠΎΡΠΎΠ², ΠΊΠΎΡΠΎΡΡΠ΅ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΡΡ Android WebView Ρ Π½Π°ΡΡΡΠΎΠΉΠΊΠΎΠΉ ΠΊΠΎΠ½ΡΠΈΠ³ΡΡΠ°ΡΠΈΠΈ ΠΏΠΎ ΡΠΌΠΎΠ»ΡΠ°Π½ΠΈΡ ΠΈ ΡΡΠΈ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ ΡΠ°Π±ΠΎΡΠ°ΡΡ Π² ΡΠΈΡΡΠ΅ΠΌΠ°Ρ Ρ Π²Π΅ΡΡΠΈΠ΅ΠΉ Android WebView Π΄ΠΎ 83.0.4103.106.
Π ΠΈΠ½ΡΡΠ°Π½ΡΠ΅ Android WebView Ρ WebSettings.setSupportMultipleWindows() = false (ΠΈΠ»ΠΈ ΠΏΠΎ ΡΠΌΠΎΠ»ΡΠ°Π½ΠΈΡ), ΠΏΠΎΠ·Π²ΠΎΠ»ΡΠ΅Ρ Π² iframe ΠΈΠ· Π΄ΡΡΠ³ΠΎΠ³ΠΎ origin ΠΎΠ±Ρ ΠΎΠ΄ΠΈΡΡ same-origin policy ΠΈ ΠΈΡΠΏΠΎΠ»Π½ΡΡΡ JS ΠΊΠΎΠ΄ Π² Π²Π΅ΡΡ Π½Π΅ΡΡΠΎΠ²Π½Π΅Π²ΠΎΠΌ Π΄ΠΎΠΊΡΠΌΠ΅Π½ΡΠ΅.
ΠΡΠ»ΠΈ Π½Π΅ ΠΏΠΎΠ΄Π΄ΡΠ΅ΠΆΠΈΠ²Π°ΡΡΡΡ Π² WebView Π½Π΅ΡΠΊΠΎΠ»ΡΠΊΠΎ ΠΎΠΊΠΎΠ½, ΡΠΎ Π½ΠΎΠ²ΡΠ΅ ΠΎΠΊΠ½Π° Ρ javascript:URL ΠΎΠ±ΡΠ°Π±Π°ΡΡΠ²Π°ΡΡΡΡ ΡΠ°ΠΊ ΠΆΠ΅, ΠΊΠ°ΠΊΠΊ Π½ΠΎΠ²ΡΠ΅ ΠΎΠΊΠ½Π° Ρ https://.
Π§ΡΠΎΠ±Ρ Π²ΡΠ·Π²Π°ΡΡ Π°ΡΠ°ΠΊΡ, iframe ΠΌΠΎΠΆΠ΅Ρ Π²ΡΠ·ΡΠ²Π°ΡΡ window.open() Ρ url-Π°Π΄ΡΠ΅ΡΠΎΠΌ javascript: URL. ΠΡΡΠ³ΠΈΠ΅ ΠΌΠ΅ΡΠΎΠ΄Ρ ΠΎΡΠΊΡΡΡΠΈΡ Π½ΠΎΠ²ΠΎΠ³ΠΎ ΠΎΠΊΠ½Π°, ΡΠ°ΠΊΠΈΠ΅ ΠΊΠ°ΠΊ ΡΡΡΠ»ΠΊΠ° Ρ target="_blank" ΠΈΠ»ΠΈ href="javascript:..." ΡΠ°ΠΊ ΠΆΠ΅ ΠΌΠΎΠ³ΡΡ ΡΡΠ°Π±ΠΎΡΠ°ΡΡ.
ΠΡ ΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΠ΅Π»Ρ ΡΡΠ΅Π±ΡΠ΅ΡΡΡ ΡΠΎΠ»ΡΠΊΠΎ ΠΎΠ΄Π½ΠΎ Π²Π·Π°ΠΈΠΌΠΎΠ΄Π΅ΠΉΡΡΠ²ΠΈΠ΅ - ΠΊΠ»ΠΈΠΊ ΠΈΠ»ΠΈ Π½Π°ΠΆΠ°ΡΠΈΠ΅ ΠΊΠ»Π°Π²ΠΈΡΠΈ, ΠΏΠΎΡΠΎΠΌΡ ΡΡΠΎ webview ΡΡΠ΅Π±ΡΠ΅Ρ Π²Π·Π°ΠΈΠΌΠΎΠ΄Π΅ΠΉΡΡΠ²ΠΈΡ, ΡΡΠΎΠ±Ρ ΠΎΡΠΊΡΡΡΡ Π½ΠΎΠ²ΠΎΠ΅ ΠΎΠΊΠ½ΠΎ.
Π ΡΠ΅Π΄ΠΊΠΈΡ ΡΠ»ΡΡΠ°ΡΡ Π²Π·Π°ΠΈΠΌΠΎΠ΄Π΅ΠΉΡΡΠ²ΠΈΠ΅ Ρ ΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΠ΅Π»Π΅ΠΌ Π½Π΅ ΡΡΠ΅Π±ΡΠ΅ΡΡΡ (drive-by attack). Π‘ΡΡΠ°Π½ΠΈΡΠ° Π²Π΅ΡΡ Π½Π΅Π³ΠΎ ΡΡΠΎΠ²Π½Ρ Π΄ΠΎΠ»ΠΆΠ½Π° Π±ΡΡΡ Π·Π°Π³ΡΡΠΆΠ΅Π½Π° Ρ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΠ΅ΠΌ ΡΡ Π΅ΠΌΡ file://, Π° WebView Π΄ΠΎΠ»ΠΆΠ΅Π½ ΡΡΡΠ°Π½ΠΎΠ²ΠΈΡΡ Π΄Π»Ρ WebSettings.setJavaScriptCanOpenWindowsAutomatically() ΠΈ WebSettings.setAllowUniversalAccessFromFileURLs() Π·Π½Π°ΡΠ΅Π½ΠΈΡ Π² true.
ΠΠ°ΠΊ ΠΏΠΎΠ½ΡΡΡ, ΡΡΠΎ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ ΡΡΠ·Π²ΠΈΠΌΠΎ?
ΠΡΠ»ΠΈ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ ΠΎΡΠΎΠ±ΡΠ°ΠΆΠ°Π΅Ρ ΡΡΡΠ°Π½ΠΈΡΡ Ρ ΠΏΠΎΠΌΠΎΡΡΡ WebViews ΠΈ ΠΎΠ±ΡΠ°Π±Π°ΡΡΠ²Π°Π΅Ρ ΠΏΠ΅ΡΠ΅Ρ ΠΎΠ΄Ρ Β«Π² Π½ΠΎΠ²ΠΎΠΌ ΠΎΠΊΠ½Π΅Β» Π² ΡΠΎΠΌ ΠΆΠ΅ ΠΎΠΊΠ½Π΅ / Π²ΠΊΠ»Π°Π΄ΠΊΠ΅ (ΡΡΠΎ ΠΎΠ·Π½Π°ΡΠ°Π΅Ρ, ΡΡΠΎ Π΄Π»Ρ ΠΏΠΎΠ΄Π΄Π΅ΡΠΆΠΊΠΈ Π½Π΅ΡΠΊΠΎΠ»ΡΠΊΠΈΡ ΠΎΠΊΠΎΠ½ ΡΡΡΠ°Π½ΠΎΠ²Π»Π΅Π½ΠΎ Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅ false), ΠΎΠ½ΠΎ, Π²Π΅ΡΠΎΡΡΠ½ΠΎ, ΡΡΠ·Π²ΠΈΠΌΠΎ. Π£Π΄ΠΈΠ²ΠΈΡΠ΅Π»ΡΠ½ΠΎ, Π½ΠΎ ΠΌΠ½ΠΎΠ³ΠΈΠ΅ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ, ΠΊΠΎΡΠΎΡΡΠ΅ ΡΠ΅Π°Π»ΠΈΠ·ΡΡΡ ΡΡΠ½ΠΊΡΠΈΡ Π½Π΅ΡΠΊΠΎΠ»ΡΠΊΠΈΡ Π²ΠΊΠ»Π°Π΄ΠΎΠΊ, ΡΡΡΠ°Π΄Π°ΡΡ, ΠΏΠΎΡΠΎΠΌΡ ΡΡΠΎ ΠΎΠ½ΠΈ ΡΠ°ΡΡΠΎ ΠΏΠΎΠ·Π²ΠΎΠ»ΡΡΡ ΠΎΡΠΊΡΡΠ²Π°ΡΡ Π½ΠΎΠ²ΡΠ΅ Π²ΠΊΠ»Π°Π΄ΠΊΠΈ ΡΠΎΠ»ΡΠΊΠΎ ΡΠ΅ΡΠ΅Π· ΡΠ²ΠΎΠΉ ΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΠ΅Π»ΡΡΠΊΠΈΠΉ ΠΈΠ½ΡΠ΅ΡΡΠ΅ΠΉΡ (Π° Π½Π΅ ΠΏΠΎ ΡΡΡΠ°Π½ΠΈΡΠ°ΠΌ Π² WebView), ΠΏΠΎΡΡΠΎΠΌΡ ΠΎΠ½ΠΈ ΠΎΡΡΠ°Π²Π»ΡΡΡ Π΄Π»Ρ ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡΠ° ΠΏΠΎΠ΄Π΄Π΅ΡΠΆΠΊΠΈ Π½Π΅ΡΠΊΠΎΠ»ΡΠΊΠΈΡ ΠΎΠΊΠΎΠ½ Android WebView Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅ false.
Π ΠΏΡΠΎΡΡΠ΅ΠΉΡΠ΅ΠΌ ΡΠ»ΡΡΠ°Π΅ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ ΡΡΠ·Π²ΠΈΠΌΠΎ, Π΅ΡΠ»ΠΈ ΠΎΠ½ΠΈ ΡΠΎΠ·Π΄Π°ΡΡ WebView ΡΠ»Π΅Π΄ΡΡΡΠΈΠΌ ΠΎΠ±ΡΠ°Π·ΠΎΠΌ:
class VulnerableActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        // ...other setup code...
        
        // Get WebView from layout
        val myWebView: WebView = findViewById(R.id.webview)
        // Enable JavaScript (only configuration required)
        myWebView.settings.javaScriptEnabled = true
        // Load parent page
        myWebView.loadUrl("https://PARENT_ORIGIN/parent.html")
    }
}ΠΡΠ»ΠΈ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ, ΠΏΠ΅ΡΠ΅ΠΉΠ΄ΠΈΡΠ΅ ΠΏΠΎ ΡΡΠΈΠΌ ΡΡΡΠ»ΠΊΠ°ΠΌ Π² ΡΠΎΠ·Π΄Π°Π½Π½ΠΎΠΉ WebView:
ΠΠΆΠΈΠ΄Π°Π΅ΠΌΠΎΠ΅ ΠΏΠΎΠ²Π΅Π΄Π΅Π½ΠΈΠ΅:
Π‘ ΡΠΊΠ°Π·Π°Π½Π½ΡΠΌΠΈ Π²ΡΡΠ΅ PoC ΠΎΠΆΠΈΠ΄Π°Π΅ΠΌΡΠΌ ΠΏΠΎΠ²Π΅Π΄Π΅Π½ΠΈΠ΅ΠΌ ΡΠ²Π»ΡΠ΅ΡΡΡ ΡΠΎ, ΡΡΠΎ JavaScript Π·Π»ΠΎΡΠΌΡΡΠ»Π΅Π½Π½ΠΈΠΊΠ° Π½Π΅ Π±ΡΠ΄Π΅Ρ Π²ΡΠΏΠΎΠ»Π½ΡΡΡΡΡ Π²ΠΎΠΎΠ±ΡΠ΅ ΠΈΠ»ΠΈ Π²ΡΠΏΠΎΠ»Π½ΡΡΡΡΡ Π² ΠΈΡΡΠΎΡΠ½ΠΈΠΊΠ΅ Π·Π»ΠΎΡΠΌΡΡΠ»Π΅Π½Π½ΠΈΠΊΠ°. Π ΡΠ»ΡΡΠ°Π΅ ΡΡΠ·Π²ΠΈΠΌΠΎΡΡΠΈ Π½Π°Π±Π»ΡΠ΄Π°Π΅ΠΌΠΎΠ΅ ΠΏΠΎΠ²Π΅Π΄Π΅Π½ΠΈΠ΅ - ΡΡΠΎ ΡΠ»Π΅ΠΌΠ΅Π½Ρ, Π΄ΠΎΠ±Π°Π²Π»ΡΠ΅ΠΌΡΠΉ Π² Π΄ΠΎΠΊΡΠΌΠ΅Π½Ρ Π²Π΅ΡΡ Π½Π΅Π³ΠΎ ΡΡΠΎΠ²Π½Ρ (ΡΠ΅Π»Ρ). Π Π·Π°Π²ΠΈΡΠΈΠΌΠΎΡΡΠΈ ΠΎΡ ΠΊΠΎΠ½ΡΠΈΠ³ΡΡΠ°ΡΠΈΠΈ WebView ΡΡΠ·Π²ΠΈΠΌΠΎΠ΅ ΠΏΠΎΠ²Π΅Π΄Π΅Π½ΠΈΠ΅ ΠΌΠΎΠΆΠ΅Ρ ΡΠ°ΠΊΠΆΠ΅ ΠΏΡΠΎΡΠ²Π»ΡΡΡΡΡ Π² Π²ΠΈΠ΄Π΅ Π΄ΠΈΠ°Π»ΠΎΠ³ΠΎΠ²ΠΎΠ³ΠΎ ΠΎΠΊΠ½Π° alert () Ρ ΠΈΠ½ΡΠΎΡΠΌΠ°ΡΠΈΠ΅ΠΉ ΠΎ ΡΠ΅Π»Π΅Π²ΠΎΠΌ ΠΏΡΠΎΠΈΡΡ ΠΎΠΆΠ΄Π΅Π½ΠΈΠΈ. (Π‘ΠΌ. ΠΠΎΠ΄Π²ΠΎΠ΄Π½ΡΠ΅ ΠΊΠ°ΠΌΠ½ΠΈ Π½ΠΈΠΆΠ΅.)
ΠΠΎΠ΄Π²ΠΎΠ΄Π½ΡΠ΅ ΠΊΠ°ΠΌΠ½ΠΈ
Depending on their configuration, WebViews may not show alert() dialog boxes. Therefore, using a payload such as javascript:alert(document.domain) is not recommended as it may yield a false-negative. Instead, use a payload which first writes to the top-level document and then tries an alert(), such as javascript:var elem = document.createElement("p"); elem.innerHTML = "<b>Executed JS in parent origin: "+window.location.origin+"</b>"; document.body.append(elem); alert(document.domain).
Mitigation
Π ΡΡΠ°ΡΡΠ΅ Π½ΠΈΠΆΠ΅ ΡΠΊΠ°Π·Π°Π½ΠΎ, ΡΡΠΎ ReactNative, Cordova ΠΈ Ionic Π½Π΅ ΠΏΠΎΡΠΈΠΊΡΠΈΠ»ΠΈ ΡΡΡ ΡΡΠ·Π²ΠΈΠΌΠΎΡΡΡ Ρ ΡΠ΅Π±Ρ.
Links
uXSS (CVE-2020-6506) - Details https://alesandroortiz.com/articles/uxss-android-webview-cve-2020-6506/ PoC: https://alesandroortiz.com/security/chromiumwebview/cve-2020-6506.html
Last updated
Was this helpful?