webview的工作、内存泄漏、漏洞以及缓存机制原理原理+方案解决
分析一段appium的日志来分析webview的工作原理,文章尾部附有自动化脚本及完整日志:
解析:
获取上下文列表

服务端发送命令adb shell cat /proc/net/unix获取域套接字列表。那什么是域套接字呢? 域套接字:是unix系统里进程与进程之间通信的一种方式。客户端想要与服务端想要连接,必须有共同的套接字和相应的服务端的端口号。套接字会一直处于监听状态,监听客户端发来的请求。 adb shell cat /proc/net/unix是获取手机端的套接字,这些套接字是用来监听外界发来的请求 adb shell cat /proc/net/unix |grep webview显示webview的套接字,其中套接字最后的数字就是进程ID

获取到webview的进程后,通过命令adb shell ps |grep 9986查询出来该进程对应的应用

匹配chromedrvier

这里是将现存的chromediver进程杀掉,并查找可以匹配webview版本的chromedriver,如果没有相对应的版本此处会报错。
查看本地和手机端的tcp连接映射关系
adb forward --list adb forward 命令是查看本地和手机端端tcp连接的映射关系

结果显示本地的57973端口和手机端的webview端口进行通信 adb forward tcp:8888 tcp:9999建立本地8888端口和手机端9999端口的映射 adb forward --remove tcp:8888删除8888端口 更多adb forward的使用方法参考:adb |grep forward 注意看:日志上是将这个映射关系给抹除了,目的是防止该进程没有被正常关闭时影响接下来的操作。
启动chromedriver

这里启动起来了chromedriver,占用的是8000端口(日志没截全,可以去看文章开头的全量日志)监听的本地的5037端口,为啥占用的是8000?在日志第303行,因为我们的脚本中没有指定端口,所以appium默认选择了一个空闲的8000端口。
创建session
这里的session是指的appium server和chromedriver之间通信的session,
转发请求,将appium server的请求转发给chromedriver
Proxying [GET /wd/hub/session/b76bb00a-43bc-4155-bd6a-ccaa3eb865b2/source] to [GET http://127.0.0.1:8000/wd/hub/session/ed7fb83742cae3d1847485e4a02ad001/source>] with body: {}
这条命令可以看出来,appium server对发到4723端口的操作,转发到了8000端口,并且session_id是appium. server 和chromedriver之间的session,本质上就是appium做了个代理,把请求进行了一次转发。
以上是我对appium 在做webview进行自动化测试时的总结,以上如有疏漏烦请各位指出,以期共同进步。
完整日志:
脚本及appium日志如下: 自动化脚本:
from appium import webdriver
from appium.webdriver.common.mobileby import MobileBy
from appium.webdriver.common.touch_action import TouchAction
class TestDemoTwo:
def setup(self):caps = {"platformName": "android","deviceName": "test","appPackage": "io.appium.android.apis","appActivity": "io.appium.android.apis.ApiDemos","noReset": "true"}self.driver = webdriver.Remote("http://localhost:4723/wd/hub", caps)self.driver.implicitly_wait(10)def teardown(self):passdef test_webview(self):view = "WebView"self.driver.find_element(MobileBy.XPATH, "//*[@text='Views']").click()# print(self.driver.contexts)self.driver.find_element(MobileBy.ANDROID_UIAUTOMATOR,f'new UiScrollable(new UiSelector().scrollable(true).instance(0)).scrollIntoView(new UiSelector().text("{view}").instance(0));').click()# 打印上下文print(self.driver.contexts)# 定位元素及操作self.driver.find_element(MobileBy.XPATH, '//*[@resource-id="i am a link"]').click()print(self.driver.contexts)# 切换上下文self.driver.switch_to.context(self.driver.contexts[-1])# self.driver.find_element(MobileBy.XPATH)# self.driver.find_element(MobileBy.XPATH, "//*[contains(@text,'other')]").get_attribute("text")print(self.driver.page_source)
appium日志:
2021-10-10 08:00:36:303 [Appium] Welcome to Appium v1.15.1
2021-10-10 08:00:36:306 [Appium] Non-default server args:
2021-10-10 08:00:36:307 [Appium] sessionOverride: true
2021-10-10 08:00:36:308 [Appium] logFile: appium1.log
2021-10-10 08:00:36:428 [Appium] Appium REST http interface listener started on 0.0.0.0:4723
2021-10-10 08:00:51:282 [HTTP] --> POST /wd/hub/session
2021-10-10 08:00:51:283 [HTTP] {"capabilities":{"firstMatch":[{"platformName":"android","appium:deviceName":"test","appium:appPackage":"io.appium.android.apis","appium:appActivity":"io.appium.android.apis.ApiDemos","appium:noReset":"true"}]},"desiredCapabilities":{"platformName":"android","deviceName":"test","appPackage":"io.appium.android.apis","appActivity":"io.appium.android.apis.ApiDemos","noReset":"true"}}
2021-10-10 08:00:51:288 [W3C] Calling AppiumDriver.createSession() with args: [{"platformName":"android","deviceName":"test","appPackage":"io.appium.android.apis","appActivity":"io.appium.android.apis.ApiDemos","noReset":"true"},null,{"firstMatch":[{"platformName":"android","appium:deviceName":"test","appium:appPackage":"io.appium.android.apis","appium:appActivity":"io.appium.android.apis.ApiDemos","appium:noReset":"true"}]}]
2021-10-10 08:00:51:290 [BaseDriver] Event 'newSessionRequested' logged at 1633852851289 (16:00:51 GMT+0800 (中国标准时间))
2021-10-10 08:00:51:305 [Appium]
2021-10-10 08:00:51:305 [Appium] ======================================================================
2021-10-10 08:00:51:306 [Appium] DEPRECATION WARNING:
2021-10-10 08:00:51:306 [Appium]
2021-10-10 08:00:51:307 [Appium] The 'automationName' capability was not provided in the desired
2021-10-10 08:00:51:308 [Appium] capabilities for this Android session
2021-10-10 08:00:51:308 [Appium]
2021-10-10 08:00:51:309 [Appium] Setting 'automationName=UiAutomator2' by default and using the
2021-10-10 08:00:51:310 [Appium] UiAutomator2 Driver
2021-10-10 08:00:51:311 [Appium]
2021-10-10 08:00:51:311 [Appium] The next major version of Appium (2.x) will **require** the
2021-10-10 08:00:51:312 [Appium] 'automationName' capability to be set for all sessions on all
2021-10-10 08:00:51:313 [Appium] platforms
2021-10-10 08:00:51:314 [Appium]
2021-10-10 08:00:51:314 [Appium] In previous versions (Appium <= 1.13.x), the default was
2021-10-10 08:00:51:315 [Appium] 'automationName=UiAutomator1'
2021-10-10 08:00:51:315 [Appium]
2021-10-10 08:00:51:315 [Appium] If you wish to use that automation instead of UiAutomator2, please
2021-10-10 08:00:51:316 [Appium] add 'automationName=UiAutomator1' to your desired capabilities
2021-10-10 08:00:51:317 [Appium]
2021-10-10 08:00:51:317 [Appium] For more information about drivers, please visit
2021-10-10 08:00:51:317 [Appium] http://appium.io/docs/en/about-appium/intro/ and explore the
2021-10-10 08:00:51:318 [Appium] 'Drivers' menu
2021-10-10 08:00:51:318 [Appium]
2021-10-10 08:00:51:318 [Appium] ======================================================================
2021-10-10 08:00:51:318 [Appium]
2021-10-10 08:00:51:828 [Appium] Appium v1.15.1 creating new AndroidUiautomator2Driver (v1.37.2) session
2021-10-10 08:00:51:833 [BaseDriver] W3C capabilities and MJSONWP desired capabilities were provided
2021-10-10 08:00:51:833 [BaseDriver] Creating session with W3C capabilities: {
2021-10-10 08:00:51:833 [BaseDriver] "alwaysMatch": {
2021-10-10 08:00:51:834 [BaseDriver] "platformName": "android",
2021-10-10 08:00:51:834 [BaseDriver] "appium:deviceName": "test",
2021-10-10 08:00:51:834 [BaseDriver] "appium:appPackage": "io.appium.android.apis",
2021-10-10 08:00:51:834 [BaseDriver] "appium:appActivity": "io.appium.android.apis.ApiDemos",
2021-10-10 08:00:51:835 [BaseDriver] "appium:noReset": "true"
2021-10-10 08:00:51:835 [BaseDriver] },
2021-10-10 08:00:51:835 [BaseDriver] "firstMatch": [
2021-10-10 08:00:51:835 [BaseDriver] {}
2021-10-10 08:00:51:836 [BaseDriver] ]
2021-10-10 08:00:51:836 [BaseDriver] }
2021-10-10 08:00:51:848 [BaseDriver] Capability 'noReset' changed from string to boolean. This may cause unexpected behavior
2021-10-10 08:00:51:855 [BaseDriver] Session created with session id: b76bb00a-43bc-4155-bd6a-ccaa3eb865b2
2021-10-10 08:00:51:857 [UiAutomator2] Starting 'io.appium.android.apis' directly on the device
2021-10-10 08:00:51:904 [ADB] Found 3 'build-tools' folders under '/Users/yujin/Library/Android/sdk' (newest first):
2021-10-10 08:00:51:904 [ADB] /Users/yujin/Library/Android/sdk/build-tools/29.0.3
2021-10-10 08:00:51:905 [ADB] /Users/yujin/Library/Android/sdk/build-tools/29.0.2
2021-10-10 08:00:51:905 [ADB] /Users/yujin/Library/Android/sdk/build-tools/28.0.3
2021-10-10 08:00:51:905 [ADB] Using 'adb' from '/Users/yujin/Library/Android/sdk/platform-tools/adb'
2021-10-10 08:00:51:906 [AndroidDriver] Retrieving device list
2021-10-10 08:00:51:906 [ADB] Trying to find a connected android device
2021-10-10 08:00:51:907 [ADB] Getting connected devices...
2021-10-10 08:00:51:932 [ADB] Connected devices: [{"udid":"emulator-5554","state":"device"}]
2021-10-10 08:00:51:933 [AndroidDriver] Using device: emulator-5554
2021-10-10 08:00:51:934 [ADB] Using 'adb' from '/Users/yujin/Library/Android/sdk/platform-tools/adb'
2021-10-10 08:00:51:935 [ADB] Setting device id to emulator-5554
2021-10-10 08:00:51:936 [ADB] Running '/Users/yujin/Library/Android/sdk/platform-tools/adb -P 5037 -s emulator-5554 shell getprop ro.build.version.sdk'
2021-10-10 08:00:51:960 [ADB] Current device property 'ro.build.version.sdk': 23
2021-10-10 08:00:51:960 [ADB] Device API level: 23
2021-10-10 08:00:51:961 [AndroidDriver] No app sent in, not parsing package/activity
2021-10-10 08:00:51:964 [ADB] Running '/Users/yujin/Library/Android/sdk/platform-tools/adb -P 5037 -s emulator-5554 wait-for-device'
2021-10-10 08:00:51:976 [ADB] Running '/Users/yujin/Library/Android/sdk/platform-tools/adb -P 5037 -s emulator-5554 shell echo ping'
2021-10-10 08:00:51:995 [AndroidDriver] Pushing settings apk to device...
2021-10-10 08:00:51:996 [ADB] Getting install status for io.appium.settings
2021-10-10 08:00:51:997 [ADB] Running '/Users/yujin/Library/Android/sdk/platform-tools/adb -P 5037 -s emulator-5554 shell dumpsys package io.appium.settings'
2021-10-10 08:00:52:047 [ADB] 'io.appium.settings' is installed
2021-10-10 08:00:52:049 [ADB] Getting package info for 'io.appium.settings'
2021-10-10 08:00:52:049 [ADB] Running '/Users/yujin/Library/Android/sdk/platform-tools/adb -P 5037 -s emulator-5554 shell dumpsys package io.appium.settings'
2021-10-10 08:00:52:081 [ADB] Using 'apkanalyzer' from '/Users/yujin/Library/Android/sdk/tools/bin/apkanalyzer'
2021-10-10 08:00:52:081 [ADB] Starting '/Users/yujin/Library/Android/sdk/tools/bin/apkanalyzer' with args ["manifest","print","/usr/local/lib/node_modules/appium/node_modules/io.appium.settings/apks/settings_apk-debug.apk"]
2021-10-10 08:00:57:066 [ADB] The version name of the installed 'io.appium.settings' is greater or equal to the application version name ('2.14.2' >= '2.14.2')
2021-10-10 08:00:57:067 [ADB] There is no need to install/upgrade '/usr/local/lib/node_modules/appium/node_modules/io.appium.settings/apks/settings_apk-debug.apk'
2021-10-10 08:00:57:068 [ADB] Getting IDs of all 'io.appium.settings' processes
2021-10-10 08:00:57:068 [ADB] Running '/Users/yujin/Library/Android/sdk/platform-tools/adb -P 5037 -s emulator-5554 shell 'pgrep --help; echo $?''
2021-10-10 08:00:57:101 [ADB] Running '/Users/yujin/Library/Android/sdk/platform-tools/adb -P 5037 -s emulator-5554 shell pgrep -f io\.appium\.settings'
2021-10-10 08:00:57:130 [AndroidDriver] io.appium.settings is already running. There is no need to reset its permissions.
2021-10-10 08:00:57:130 [ADB] Running '/Users/yujin/Library/Android/sdk/platform-tools/adb -P 5037 -s emulator-5554 shell appops set io.appium.settings android:mock_location allow'
2021-10-10 08:00:58:217 [Logcat] Starting logcat capture
2021-10-10 08:00:58:313 [ADB] Getting install status for io.appium.uiautomator2.server
2021-10-10 08:00:58:315 [ADB] Running '/Users/yujin/Library/Android/sdk/platform-tools/adb -P 5037 -s emulator-5554 shell dumpsys package io.appium.uiautomator2.server'
2021-10-10 08:00:58:390 [ADB] 'io.appium.uiautomator2.server' is installed
2021-10-10 08:00:58:393 [ADB] Getting package info for 'io.appium.uiautomator2.server'
2021-10-10 08:00:58:395 [ADB] Running '/Users/yujin/Library/Android/sdk/platform-tools/adb -P 5037 -s emulator-5554 shell dumpsys package io.appium.uiautomator2.server'
2021-10-10 08:00:58:446 [ADB] Starting '/Users/yujin/Library/Android/sdk/tools/bin/apkanalyzer' with args ["manifest","print","/usr/local/lib/node_modules/appium/node_modules/appium-uiautomator2-server/apks/appium-uiautomator2-server-v4.3.0.apk"]
2021-10-10 08:01:01:855 [ADB] The version name of the installed 'io.appium.uiautomator2.server' is greater or equal to the application version name ('4.3.0' >= '4.3.0')
2021-10-10 08:01:01:856 [UiAutomator2] io.appium.uiautomator2.server installation state: sameVersionInstalled
2021-10-10 08:01:01:857 [ADB] Checking app cert for /usr/local/lib/node_modules/appium/node_modules/appium-uiautomator2-server/apks/appium-uiautomator2-server-v4.3.0.apk
2021-10-10 08:01:01:860 [ADB] Using 'apksigner' from '/Users/yujin/Library/Android/sdk/build-tools/29.0.3/apksigner'
2021-10-10 08:01:01:861 [ADB] Starting '/Users/yujin/Library/Android/sdk/build-tools/29.0.3/apksigner' with args '["verify","--print-certs","/usr/local/lib/node_modules/appium/node_modules/appium-uiautomator2-server/apks/appium-uiautomator2-server-v4.3.0.apk"]'
2021-10-10 08:01:03:145 [ADB] apksigner stdout: Signer #1 certificate DN: EMAILADDRESS=android@android.com, CN=Android, OU=Android, O=Android, L=Mountain View, ST=California, C=US
2021-10-10 08:01:03:145 [ADB] Signer #1 certificate SHA-256 digest: a40da80a59d170caa950cf15c18c454d47a39b26989d8b640ecd745ba71bf5dc
2021-10-10 08:01:03:146 [ADB] Signer #1 certificate SHA-1 digest: 61ed377e85d386a8dfee6b864bd85b0bfaa5af81
2021-10-10 08:01:03:147 [ADB] Signer #1 certificate MD5 digest: e89b158e4bcf988ebd09eb83f5378e87
2021-10-10 08:01:03:147 [ADB]
2021-10-10 08:01:03:147 [ADB] '/usr/local/lib/node_modules/appium/node_modules/appium-uiautomator2-server/apks/appium-uiautomator2-server-v4.3.0.apk' is already signed.
2021-10-10 08:01:03:148 [ADB] Getting install status for io.appium.uiautomator2.server.test
2021-10-10 08:01:03:148 [ADB] Running '/Users/yujin/Library/Android/sdk/platform-tools/adb -P 5037 -s emulator-5554 shell dumpsys package io.appium.uiautomator2.server.test'
2021-10-10 08:01:03:189 [ADB] 'io.appium.uiautomator2.server.test' is installed
2021-10-10 08:01:03:189 [ADB] Checking app cert for /usr/local/lib/node_modules/appium/node_modules/appium-uiautomator2-server/apks/appium-uiautomator2-server-debug-androidTest.apk
2021-10-10 08:01:03:190 [ADB] Starting '/Users/yujin/Library/Android/sdk/build-tools/29.0.3/apksigner' with args '["verify","--print-certs","/usr/local/lib/node_modules/appium/node_modules/appium-uiautomator2-server/apks/appium-uiautomator2-server-debug-androidTest.apk"]'
2021-10-10 08:01:04:340 [ADB] apksigner stdout: Signer #1 certificate DN: EMAILADDRESS=android@android.com, CN=Android, OU=Android, O=Android, L=Mountain View, ST=California, C=US
2021-10-10 08:01:04:340 [ADB] Signer #1 certificate SHA-256 digest: a40da80a59d170caa950cf15c18c454d47a39b26989d8b640ecd745ba71bf5dc
2021-10-10 08:01:04:341 [ADB] Signer #1 certificate SHA-1 digest: 61ed377e85d386a8dfee6b864bd85b0bfaa5af81
2021-10-10 08:01:04:341 [ADB] Signer #1 certificate MD5 digest: e89b158e4bcf988ebd09eb83f5378e87
2021-10-10 08:01:04:343 [ADB]
2021-10-10 08:01:04:343 [ADB] '/usr/local/lib/node_modules/appium/node_modules/appium-uiautomator2-server/apks/appium-uiautomator2-server-debug-androidTest.apk' is already signed.
2021-10-10 08:01:04:343 [UiAutomator2] Server packages are not going to be (re)installed
2021-10-10 08:01:04:350 [UiAutomator2] Waiting up to 30000ms for services to be available
2021-10-10 08:01:04:351 [ADB] Running '/Users/yujin/Library/Android/sdk/platform-tools/adb -P 5037 -s emulator-5554 shell pm list instrumentation'
2021-10-10 08:01:04:718 [UiAutomator2] Instrumentation target 'io.appium.uiautomator2.server.test/androidx.test.runner.AndroidJUnitRunner' is available
2021-10-10 08:01:04:718 [UiAutomator2] Forwarding UiAutomator2 Server port 6790 to 8200
2021-10-10 08:01:04:719 [ADB] Forwarding system: 8200 to device: 6790
2021-10-10 08:01:04:721 [ADB] Running '/Users/yujin/Library/Android/sdk/platform-tools/adb -P 5037 -s emulator-5554 forward tcp:8200 tcp:6790'
2021-10-10 08:01:04:738 [UiAutomator2] No app capability. Assuming it is already on the device
2021-10-10 08:01:04:739 [UiAutomator2] Performing shallow cleanup of automation leftovers
2021-10-10 08:01:04:770 [UiAutomator2] No obsolete sessions have been detected (Error: socket hang up)
2021-10-10 08:01:04:770 [ADB] Running '/Users/yujin/Library/Android/sdk/platform-tools/adb -P 5037 -s emulator-5554 shell am force-stop io.appium.uiautomator2.server.test'
2021-10-10 08:01:05:311 [UiAutomator2] Starting UIAutomator2 server 4.3.0
2021-10-10 08:01:05:312 [UiAutomator2] Using UIAutomator2 server from '/usr/local/lib/node_modules/appium/node_modules/appium-uiautomator2-server/apks/appium-uiautomator2-server-v4.3.0.apk' and test from '/usr/local/lib/node_modules/appium/node_modules/appium-uiautomator2-server/apks/appium-uiautomator2-server-debug-androidTest.apk'
2021-10-10 08:01:05:312 [UiAutomator2] Waiting up to 30000ms for UiAutomator2 to be online...
2021-10-10 08:01:05:313 [ADB] Creating ADB subprocess with args: ["-P",5037,"-s","emulator-5554","shell","am","instrument","-w","io.appium.uiautomator2.server.test/androidx.test.runner.AndroidJUnitRunner"]
2021-10-10 08:01:06:069 [Instrumentation] io.appium.uiautomator2.server.test.AppiumUiAutomator2Server:
2021-10-10 08:01:06:326 [WD Proxy] Matched '/status' to command name 'getStatus'
2021-10-10 08:01:06:328 [WD Proxy] Proxying [GET /status] to [GET http://localhost:8200/wd/hub/status] with no body
2021-10-10 08:01:06:335 [WD Proxy] Got an unexpected response with status undefined: {"code":"ECONNRESET"}
2021-10-10 08:01:07:341 [WD Proxy] Matched '/status' to command name 'getStatus'
2021-10-10 08:01:07:343 [WD Proxy] Proxying [GET /status] to [GET http://localhost:8200/wd/hub/status] with no body
2021-10-10 08:01:07:398 [WD Proxy] Got response with status 200: {"sessionId":"None","value":{"ready":true,"message":"UiAutomator2 Server is ready to accept commands"}}
2021-10-10 08:01:07:399 [UiAutomator2] The initialization of the instrumentation process took 2087ms
2021-10-10 08:01:07:401 [WD Proxy] Matched '/session' to command name 'createSession'
2021-10-10 08:01:07:403 [WD Proxy] Proxying [POST /session] to [POST http://localhost:8200/wd/hub/session] with body: {"capabilities":{"firstMatch":[{"platform":"LINUX","webStorageEnabled":false,"takesScreenshot":true,"javascriptEnabled":true,"databaseEnabled":false,"networkConnectionEnabled":true,"locationContextEnabled":false,"warnings":{},"desired":{"platformName":"android","deviceName":"test","appPackage":"io.appium.android.apis","appActivity":"io.appium.android.apis.ApiDemos","noReset":true},"platformName":"android","deviceName":"emulator-5554","appPackage":"io.appium.android.apis","appActivity":"io.appium.android.apis.ApiDemos","noReset":true,"deviceUDID":"emulator-5554"}],"alwaysMatch":{}}}
2021-10-10 08:01:07:420 [WD Proxy] Got response with status 200: {"sessionId":"1f7ceff4-e731-4b38-b43f-7fde4ed9268a","value":{"sessionId":"1f7ceff4-e731-4b38-b43f-7fde4ed9268a","capabilities":{"firstMatch":[{"platform":"LINUX","webStorageEnabled":false,"takesScreenshot":true,"javascriptEnabled":true,"databaseEnabled":false,"networkConnectionEnabled":true,"locationContextEnabled":false,"warnings":{},"desired":{"platformName":"android","deviceName":"test","appPackage":"io.appium.android.apis","appActivity":"io.appium.android.apis.ApiDemos","noReset":true},"platformName":"android","deviceName":"emulator-5554","appPackage":"io.appium.android.apis","appActivity":"io.appium.android.apis.ApiDemos","noReset":true,"deviceUDID":"emulator-5554"}],"alwaysMatch":{}}}}
2021-10-10 08:01:07:420 [WD Proxy] Determined the downstream protocol as 'W3C'
2021-10-10 08:01:07:437 [WD Proxy] Proxying [GET /appium/device/info] to [GET http://localhost:8200/wd/hub/session/1f7ceff4-e731-4b38-b43f-7fde4ed9268a/appium/device/info] with no body
2021-10-10 08:01:07:462 [WD Proxy] Got response with status 200: {"sessionId":"1f7ceff4-e731-4b38-b43f-7fde4ed9268a","value":{"androidId":"eeccdb17137abe38","manufacturer":"Netease","model":"MuMu","brand":"Android","apiVersion":"23","platformVersion":"6.0.1","carrierName":"","realDisplaySize":"720x1280","displayDensity":280,"networks":[{"type":1,"typeName":"WIFI","subtype":0,"subtypeName":"","isConnected":true,"detailedState":"CONNECTED","state":"CONNECTED","extraInfo":""u4b3zvSCE43"","isAvailable":true,"isFailover":false,"isRoaming":false,"capabilities":{"transportTypes":"NET_CAPABILITY_SUPL","networkCapabilities":"","linkUpstreamBandwidthKbps":1048576,"linkDownBandwidthKbps":1048576,"signalStrength":-55,"networkSpecifier":null,"SSID":null}}],"locale":"zh_CN","timeZone":"Asia/Shanghai"}}
2021-10-10 08:01:07:463 [ADB] Running '/Users/yujin/Library/Android/sdk/platform-tools/adb -P 5037 -s emulator-5554 shell dumpsys window'
2021-10-10 08:01:07:500 [AndroidDriver] Screen already unlocked, doing nothing
2021-10-10 08:01:07:502 [UiAutomator2] Starting 'io.appium.android.apis/io.appium.android.apis.ApiDemos and waiting for 'io.appium.android.apis/io.appium.android.apis.ApiDemos'
2021-10-10 08:01:07:503 [ADB] Running '/Users/yujin/Library/Android/sdk/platform-tools/adb -P 5037 -s emulator-5554 shell am start -W -n io.appium.android.apis/io.appium.android.apis.ApiDemos -S -a android.intent.action.MAIN -c android.intent.category.LAUNCHER -f 0x10200000'
2021-10-10 08:01:09:768 [WD Proxy] Proxying [GET /appium/device/pixel_ratio] to [GET http://localhost:8200/wd/hub/session/1f7ceff4-e731-4b38-b43f-7fde4ed9268a/appium/device/pixel_ratio] with body: {}
2021-10-10 08:01:09:838 [WD Proxy] Got response with status 200: {"sessionId":"1f7ceff4-e731-4b38-b43f-7fde4ed9268a","value":1.75}
2021-10-10 08:01:09:840 [WD Proxy] Matched '/appium/device/system_bars' to command name 'getSystemBars'
2021-10-10 08:01:09:841 [WD Proxy] Proxying [GET /appium/device/system_bars] to [GET http://localhost:8200/wd/hub/session/1f7ceff4-e731-4b38-b43f-7fde4ed9268a/appium/device/system_bars] with body: {}
2021-10-10 08:01:09:861 [WD Proxy] Got response with status 200: {"sessionId":"1f7ceff4-e731-4b38-b43f-7fde4ed9268a","value":{"statusBar":42}}
2021-10-10 08:01:09:862 [WD Proxy] Matched '/window/current/size' to command name 'getWindowSize'
2021-10-10 08:01:09:862 [WD Proxy] Proxying [GET /window/current/size] to [GET http://localhost:8200/wd/hub/session/1f7ceff4-e731-4b38-b43f-7fde4ed9268a/window/current/size] with body: {}
2021-10-10 08:01:09:872 [WD Proxy] Got response with status 200: {"sessionId":"1f7ceff4-e731-4b38-b43f-7fde4ed9268a","value":{"height":1280,"width":720}}
2021-10-10 08:01:09:873 [Appium] New AndroidUiautomator2Driver session created successfully, session b76bb00a-43bc-4155-bd6a-ccaa3eb865b2 added to master session list
2021-10-10 08:01:09:874 [BaseDriver] Event 'newSessionStarted' logged at 1633852869874 (16:01:09 GMT+0800 (中国标准时间))
2021-10-10 08:01:09:875 [W3C (b76bb00a)] Cached the protocol value 'W3C' for the new session b76bb00a-43bc-4155-bd6a-ccaa3eb865b2
2021-10-10 08:01:09:879 [W3C (b76bb00a)] Responding to client with driver.createSession() result: {"capabilities":{"platform":"LINUX","webStorageEnabled":false,"takesScreenshot":true,"javascriptEnabled":true,"databaseEnabled":false,"networkConnectionEnabled":true,"locationContextEnabled":false,"warnings":{},"desired":{"platformName":"android","deviceName":"test","appPackage":"io.appium.android.apis","appActivity":"io.appium.android.apis.ApiDemos","noReset":true},"platformName":"android","deviceName":"emulator-5554","appPackage":"io.appium.android.apis","appActivity":"io.appium.android.apis.ApiDemos","noReset":true,"deviceUDID":"emulator-5554","deviceApiLevel":23,"platformVersion":"6.0.1","deviceScreenSize":"720x1280","deviceScreenDensity":280,"deviceModel":"MuMu","deviceManufacturer":"Netease","pixelRatio":1.75,"statBarHeight":42,"viewportRect":{"left":0,"top":42,"width":720,"height":1238}}}
2021-10-10 08:01:09:884 [HTTP] <-- POST /wd/hub/session 200 18599 ms - 867
2021-10-10 08:01:09:884 [HTTP]
2021-10-10 08:01:09:889 [HTTP] --> POST /wd/hub/session/b76bb00a-43bc-4155-bd6a-ccaa3eb865b2/timeouts
2021-10-10 08:01:09:890 [HTTP] {"implicit":10000}
2021-10-10 08:01:09:893 [W3C (b76bb00a)] Calling AppiumDriver.timeouts() with args: [null,null,null,null,10000,"b76bb00a-43bc-4155-bd6a-ccaa3eb865b2"]
2021-10-10 08:01:09:943 [BaseDriver] W3C timeout argument: {"implicit":10000}}
2021-10-10 08:01:09:944 [BaseDriver] Set implicit wait to 10000ms
2021-10-10 08:01:09:945 [W3C (b76bb00a)] Responding to client with driver.timeouts() result: null
2021-10-10 08:01:09:947 [HTTP] <-- POST /wd/hub/session/b76bb00a-43bc-4155-bd6a-ccaa3eb865b2/timeouts 200 57 ms - 14
2021-10-10 08:01:09:948 [HTTP]
2021-10-10 08:01:09:957 [HTTP] --> POST /wd/hub/session/b76bb00a-43bc-4155-bd6a-ccaa3eb865b2/element
2021-10-10 08:01:09:958 [HTTP] {"using":"xpath","value":"//*[@text='Views']"}
2021-10-10 08:01:09:961 [W3C (b76bb00a)] Calling AppiumDriver.findElement() with args: ["xpath","//*[@text='Views']","b76bb00a-43bc-4155-bd6a-ccaa3eb865b2"]
2021-10-10 08:01:09:963 [BaseDriver] Valid locator strategies for this request: xpath, id, class name, accessibility id, -android uiautomator
2021-10-10 08:01:09:964 [BaseDriver] Waiting up to 10000 ms for condition
2021-10-10 08:01:09:966 [WD Proxy] Matched '/element' to command name 'findElement'
2021-10-10 08:01:09:966 [WD Proxy] Proxying [POST /element] to [POST http://localhost:8200/wd/hub/session/1f7ceff4-e731-4b38-b43f-7fde4ed9268a/element] with body: {"strategy":"xpath","selector":"//*[@text='Views']","context":"","multiple":false}
2021-10-10 08:01:10:283 [WD Proxy] Got response with status 200: {"sessionId":"1f7ceff4-e731-4b38-b43f-7fde4ed9268a","value":{"ELEMENT":"f2eed02a-5ae0-47bb-8a7d-cf9a10f242c2","element-6066-11e4-a52e-4f735466cecf":"f2eed02a-5ae0-47bb-8a7d-cf9a10f242c2"}}
2021-10-10 08:01:10:284 [W3C (b76bb00a)] Responding to client with driver.findElement() result: {"element-6066-11e4-a52e-4f735466cecf":"f2eed02a-5ae0-47bb-8a7d-cf9a10f242c2","ELEMENT":"f2eed02a-5ae0-47bb-8a7d-cf9a10f242c2"}
2021-10-10 08:01:10:285 [HTTP] <-- POST /wd/hub/session/b76bb00a-43bc-4155-bd6a-ccaa3eb865b2/element 200 329 ms - 137
2021-10-10 08:01:10:286 [HTTP]
2021-10-10 08:01:10:291 [HTTP] --> POST /wd/hub/session/b76bb00a-43bc-4155-bd6a-ccaa3eb865b2/element/f2eed02a-5ae0-47bb-8a7d-cf9a10f242c2/click
2021-10-10 08:01:10:291 [HTTP] {"id":"f2eed02a-5ae0-47bb-8a7d-cf9a10f242c2"}
2021-10-10 08:01:10:294 [W3C (b76bb00a)] Calling AppiumDriver.click() with args: ["f2eed02a-5ae0-47bb-8a7d-cf9a10f242c2","b76bb00a-43bc-4155-bd6a-ccaa3eb865b2"]
2021-10-10 08:01:10:295 [WD Proxy] Matched '/element/f2eed02a-5ae0-47bb-8a7d-cf9a10f242c2/click' to command name 'click'
2021-10-10 08:01:10:296 [WD Proxy] Proxying [POST /element/f2eed02a-5ae0-47bb-8a7d-cf9a10f242c2/click] to [POST http://localhost:8200/wd/hub/session/1f7ceff4-e731-4b38-b43f-7fde4ed9268a/element/f2eed02a-5ae0-47bb-8a7d-cf9a10f242c2/click] with body: {"element":"f2eed02a-5ae0-47bb-8a7d-cf9a10f242c2"}
2021-10-10 08:01:11:397 [WD Proxy] Got response with status 200: {"sessionId":"1f7ceff4-e731-4b38-b43f-7fde4ed9268a","value":null}
2021-10-10 08:01:11:400 [W3C (b76bb00a)] Responding to client with driver.click() result: null
2021-10-10 08:01:11:402 [HTTP] <-- POST /wd/hub/session/b76bb00a-43bc-4155-bd6a-ccaa3eb865b2/element/f2eed02a-5ae0-47bb-8a7d-cf9a10f242c2/click 200 1110 ms - 14
2021-10-10 08:01:11:402 [HTTP]
2021-10-10 08:01:11:405 [HTTP] --> POST /wd/hub/session/b76bb00a-43bc-4155-bd6a-ccaa3eb865b2/element
2021-10-10 08:01:11:405 [HTTP] {"using":"-android uiautomator","value":"new UiScrollable(new UiSelector().scrollable(true).instance(0)).scrollIntoView(new UiSelector().text("WebView").instance(0));"}
2021-10-10 08:01:11:406 [W3C (b76bb00a)] Calling AppiumDriver.findElement() with args: ["-android uiautomator","new UiScrollable(new UiSelector().scrollable(true).instance(0)).scrollIntoView(new UiSelector().text("WebView").instance(0));","b76bb00a-43bc-4155-bd6a-ccaa3eb865b2"]
2021-10-10 08:01:11:407 [BaseDriver] Valid locator strategies for this request: xpath, id, class name, accessibility id, -android uiautomator
2021-10-10 08:01:11:407 [BaseDriver] Waiting up to 10000 ms for condition
2021-10-10 08:01:11:408 [WD Proxy] Matched '/element' to command name 'findElement'
2021-10-10 08:01:11:408 [WD Proxy] Proxying [POST /element] to [POST http://localhost:8200/wd/hub/session/1f7ceff4-e731-4b38-b43f-7fde4ed9268a/element] with body: {"strategy":"-android uiautomator","selector":"new UiScrollable(new UiSelector().scrollable(true).instance(0)).scrollIntoView(new UiSelector().text("WebView").instance(0));","context":"","multiple":false}
2021-10-10 08:01:20:730 [WD Proxy] Got response with status 200: {"sessionId":"1f7ceff4-e731-4b38-b43f-7fde4ed9268a","value":{"ELEMENT":"4010cba7-b08f-494c-a543-24a1d871b8d1","element-6066-11e4-a52e-4f735466cecf":"4010cba7-b08f-494c-a543-24a1d871b8d1"}}
2021-10-10 08:01:20:731 [W3C (b76bb00a)] Responding to client with driver.findElement() result: {"element-6066-11e4-a52e-4f735466cecf":"4010cba7-b08f-494c-a543-24a1d871b8d1","ELEMENT":"4010cba7-b08f-494c-a543-24a1d871b8d1"}
2021-10-10 08:01:20:734 [HTTP] <-- POST /wd/hub/session/b76bb00a-43bc-4155-bd6a-ccaa3eb865b2/element 200 9326 ms - 137
2021-10-10 08:01:20:734 [HTTP]
2021-10-10 08:01:20:737 [HTTP] --> POST /wd/hub/session/b76bb00a-43bc-4155-bd6a-ccaa3eb865b2/element/4010cba7-b08f-494c-a543-24a1d871b8d1/click
2021-10-10 08:01:20:738 [HTTP] {"id":"4010cba7-b08f-494c-a543-24a1d871b8d1"}
2021-10-10 08:01:20:739 [W3C (b76bb00a)] Calling AppiumDriver.click() with args: ["4010cba7-b08f-494c-a543-24a1d871b8d1","b76bb00a-43bc-4155-bd6a-ccaa3eb865b2"]
2021-10-10 08:01:20:740 [WD Proxy] Matched '/element/4010cba7-b08f-494c-a543-24a1d871b8d1/click' to command name 'click'
2021-10-10 08:01:20:741 [WD Proxy] Proxying [POST /element/4010cba7-b08f-494c-a543-24a1d871b8d1/click] to [POST http://localhost:8200/wd/hub/session/1f7ceff4-e731-4b38-b43f-7fde4ed9268a/element/4010cba7-b08f-494c-a543-24a1d871b8d1/click] with body: {"element":"4010cba7-b08f-494c-a543-24a1d871b8d1"}
2021-10-10 08:01:21:503 [WD Proxy] Got response with status 200: {"sessionId":"1f7ceff4-e731-4b38-b43f-7fde4ed9268a","value":null}
2021-10-10 08:01:21:504 [W3C (b76bb00a)] Responding to client with driver.click() result: null
2021-10-10 08:01:21:506 [HTTP] <-- POST /wd/hub/session/b76bb00a-43bc-4155-bd6a-ccaa3eb865b2/element/4010cba7-b08f-494c-a543-24a1d871b8d1/click 200 768 ms - 14
2021-10-10 08:01:21:508 [HTTP]
2021-10-10 08:01:21:511 [HTTP] --> GET /wd/hub/session/b76bb00a-43bc-4155-bd6a-ccaa3eb865b2/contexts
2021-10-10 08:01:21:512 [HTTP] {}
2021-10-10 08:01:21:518 [W3C (b76bb00a)] Calling AppiumDriver.getContexts() with args: ["b76bb00a-43bc-4155-bd6a-ccaa3eb865b2"]
2021-10-10 08:01:21:520 [AndroidDriver] Getting a list of available webviews
2021-10-10 08:01:21:521 [ADB] Running '/Users/yujin/Library/Android/sdk/platform-tools/adb -P 5037 -s emulator-5554 shell cat /proc/net/unix'
2021-10-10 08:01:21:608 [AndroidDriver] Not checking whether webviews have active pages; use the 'ensureWebviewsHavePages' cap to turn this check on
2021-10-10 08:01:21:611 [AndroidDriver] Found webviews: []
2021-10-10 08:01:21:612 [AndroidDriver] Available contexts: ["NATIVE_APP"]
2021-10-10 08:01:21:613 [W3C (b76bb00a)] Responding to client with driver.getContexts() result: ["NATIVE_APP"]
2021-10-10 08:01:21:617 [HTTP] <-- GET /wd/hub/session/b76bb00a-43bc-4155-bd6a-ccaa3eb865b2/contexts 200 106 ms - 24
2021-10-10 08:01:21:618 [HTTP]
2021-10-10 08:01:21:623 [HTTP] --> POST /wd/hub/session/b76bb00a-43bc-4155-bd6a-ccaa3eb865b2/element
2021-10-10 08:01:21:624 [HTTP] {"using":"xpath","value":"//*[@resource-id="i am a link"]"}
2021-10-10 08:01:21:627 [W3C (b76bb00a)] Calling AppiumDriver.findElement() with args: ["xpath","//*[@resource-id="i am a link"]","b76bb00a-43bc-4155-bd6a-ccaa3eb865b2"]
2021-10-10 08:01:21:630 [BaseDriver] Valid locator strategies for this request: xpath, id, class name, accessibility id, -android uiautomator
2021-10-10 08:01:21:631 [BaseDriver] Waiting up to 10000 ms for condition
2021-10-10 08:01:21:634 [WD Proxy] Matched '/element' to command name 'findElement'
2021-10-10 08:01:21:636 [WD Proxy] Proxying [POST /element] to [POST http://localhost:8200/wd/hub/session/1f7ceff4-e731-4b38-b43f-7fde4ed9268a/element] with body: {"strategy":"xpath","selector":"//*[@resource-id="i am a link"]","context":"","multiple":false}
2021-10-10 08:01:22:194 [WD Proxy] Got an unexpected response with status 404: {"sessionId":"1f7ceff4-e731-4b38-b43f-7fde4ed9268a","value":{"error":"no such element","message":"An element could not be located on the page using the given search parameters","stacktrace":"io.appium.uiautomator2.common.exceptions.ElementNotFoundException: An element could not be located on the page using the given search parameters\n\tat io.appium.uiautomator2.handler.FindElement.findElement(FindElement.java:102)\n\tat io.appium.uiautomator2.handler.FindElement.safeHandle(FindElement.java:72)\n\tat io.appium.uiautomator2.handler.request.SafeRequestHandler.handle(SafeRequestHandler.java:38)\n\tat io.appium.uiautomator2.server.AppiumServlet.handleRequest(AppiumServlet.java:252)\n\tat io.appium.uiautomator2.server.AppiumServlet.handleHttpRequest(AppiumServlet.java:242)\n\tat io.appium.uiautomator2.http.ServerHandler.channelRead(ServerHandler.java:44)\n\tat io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:366)\n\tat io.netty.channel.AbstractChannelHandlerCon...
2021-10-10 08:01:22:195 [W3C] Matched W3C error code 'no such element' to NoSuchElementError
2021-10-10 08:01:22:196 [BaseDriver] Waited for 565 ms so far
2021-10-10 08:01:22:697 [WD Proxy] Matched '/element' to command name 'findElement'
2021-10-10 08:01:22:698 [WD Proxy] Proxying [POST /element] to [POST http://localhost:8200/wd/hub/session/1f7ceff4-e731-4b38-b43f-7fde4ed9268a/element] with body: {"strategy":"xpath","selector":"//*[@resource-id="i am a link"]","context":"","multiple":false}
2021-10-10 08:01:23:948 [WD Proxy] Got an unexpected response with status 404: {"sessionId":"1f7ceff4-e731-4b38-b43f-7fde4ed9268a","value":{"error":"no such element","message":"An element could not be located on the page using the given search parameters","stacktrace":"io.appium.uiautomator2.common.exceptions.ElementNotFoundException: An element could not be located on the page using the given search parameters\n\tat io.appium.uiautomator2.handler.FindElement.findElement(FindElement.java:102)\n\tat io.appium.uiautomator2.handler.FindElement.safeHandle(FindElement.java:72)\n\tat io.appium.uiautomator2.handler.request.SafeRequestHandler.handle(SafeRequestHandler.java:38)\n\tat io.appium.uiautomator2.server.AppiumServlet.handleRequest(AppiumServlet.java:252)\n\tat io.appium.uiautomator2.server.AppiumServlet.handleHttpRequest(AppiumServlet.java:242)\n\tat io.appium.uiautomator2.http.ServerHandler.channelRead(ServerHandler.java:44)\n\tat io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:366)\n\tat io.netty.channel.AbstractChannelHandlerCon...
2021-10-10 08:01:23:948 [W3C] Matched W3C error code 'no such element' to NoSuchElementError
2021-10-10 08:01:23:949 [BaseDriver] Waited for 2318 ms so far
2021-10-10 08:01:24:455 [WD Proxy] Matched '/element' to command name 'findElement'
2021-10-10 08:01:24:456 [WD Proxy] Proxying [POST /element] to [POST http://localhost:8200/wd/hub/session/1f7ceff4-e731-4b38-b43f-7fde4ed9268a/element] with body: {"strategy":"xpath","selector":"//*[@resource-id="i am a link"]","context":"","multiple":false}
2021-10-10 08:01:24:714 [WD Proxy] Got response with status 200: {"sessionId":"1f7ceff4-e731-4b38-b43f-7fde4ed9268a","value":{"ELEMENT":"eea82ab1-38d9-41c0-be30-edf8637af535","element-6066-11e4-a52e-4f735466cecf":"eea82ab1-38d9-41c0-be30-edf8637af535"}}
2021-10-10 08:01:24:716 [W3C (b76bb00a)] Responding to client with driver.findElement() result: {"element-6066-11e4-a52e-4f735466cecf":"eea82ab1-38d9-41c0-be30-edf8637af535","ELEMENT":"eea82ab1-38d9-41c0-be30-edf8637af535"}
2021-10-10 08:01:24:717 [HTTP] <-- POST /wd/hub/session/b76bb00a-43bc-4155-bd6a-ccaa3eb865b2/element 200 3094 ms - 137
2021-10-10 08:01:24:718 [HTTP]
2021-10-10 08:01:24:724 [HTTP] --> POST /wd/hub/session/b76bb00a-43bc-4155-bd6a-ccaa3eb865b2/element/eea82ab1-38d9-41c0-be30-edf8637af535/click
2021-10-10 08:01:24:724 [HTTP] {"id":"eea82ab1-38d9-41c0-be30-edf8637af535"}
2021-10-10 08:01:24:726 [W3C (b76bb00a)] Calling AppiumDriver.click() with args: ["eea82ab1-38d9-41c0-be30-edf8637af535","b76bb00a-43bc-4155-bd6a-ccaa3eb865b2"]
2021-10-10 08:01:24:728 [WD Proxy] Matched '/element/eea82ab1-38d9-41c0-be30-edf8637af535/click' to command name 'click'
2021-10-10 08:01:24:729 [WD Proxy] Proxying [POST /element/eea82ab1-38d9-41c0-be30-edf8637af535/click] to [POST http://localhost:8200/wd/hub/session/1f7ceff4-e731-4b38-b43f-7fde4ed9268a/element/eea82ab1-38d9-41c0-be30-edf8637af535/click] with body: {"element":"eea82ab1-38d9-41c0-be30-edf8637af535"}
2021-10-10 08:01:24:782 [WD Proxy] Got response with status 200: {"sessionId":"1f7ceff4-e731-4b38-b43f-7fde4ed9268a","value":null}
2021-10-10 08:01:24:787 [W3C (b76bb00a)] Responding to client with driver.click() result: null
2021-10-10 08:01:24:790 [HTTP] <-- POST /wd/hub/session/b76bb00a-43bc-4155-bd6a-ccaa3eb865b2/element/eea82ab1-38d9-41c0-be30-edf8637af535/click 200 65 ms - 14
2021-10-10 08:01:24:790 [HTTP]
2021-10-10 08:01:24:794 [HTTP] --> GET /wd/hub/session/b76bb00a-43bc-4155-bd6a-ccaa3eb865b2/contexts
2021-10-10 08:01:24:795 [HTTP] {}
2021-10-10 08:01:24:800 [W3C (b76bb00a)] Calling AppiumDriver.getContexts() with args: ["b76bb00a-43bc-4155-bd6a-ccaa3eb865b2"]
2021-10-10 08:01:24:802 [AndroidDriver] Getting a list of available webviews
2021-10-10 08:01:24:802 [ADB] Running '/Users/yujin/Library/Android/sdk/platform-tools/adb -P 5037 -s emulator-5554 shell cat /proc/net/unix'
2021-10-10 08:01:24:907 [AndroidDriver] Not checking whether webviews have active pages; use the 'ensureWebviewsHavePages' cap to turn this check on
2021-10-10 08:01:24:910 [AndroidDriver] WEBVIEW_2632 mapped to pid 2632
2021-10-10 08:01:24:911 [AndroidDriver] Getting process name for webview
2021-10-10 08:01:24:912 [ADB] Running '/Users/yujin/Library/Android/sdk/platform-tools/adb -P 5037 -s emulator-5554 shell ps'
2021-10-10 08:01:25:026 [AndroidDriver] Parsed pid: '2632' pkg: 'io.appium.android.apis' from
2021-10-10 08:01:25:026 [AndroidDriver] USER PID PPID VSIZE RSS WCHAN PC NAME
2021-10-10 08:01:25:026 [AndroidDriver] u0_a45 2632 291 1136340 120932 0 7f80807c0ea8 S io.appium.android.apis
2021-10-10 08:01:25:027 [AndroidDriver] Returning process name: 'io.appium.android.apis'
2021-10-10 08:01:25:030 [AndroidDriver] Found webviews: ["WEBVIEW_io.appium.android.apis"]
2021-10-10 08:01:25:030 [AndroidDriver] Available contexts: ["NATIVE_APP","WEBVIEW_io.appium.android.apis"]
2021-10-10 08:01:25:031 [W3C (b76bb00a)] Responding to client with driver.getContexts() result: ["NATIVE_APP","WEBVIEW_io.appium.android.apis"]
2021-10-10 08:01:25:036 [HTTP] <-- GET /wd/hub/session/b76bb00a-43bc-4155-bd6a-ccaa3eb865b2/contexts 200 241 ms - 57
2021-10-10 08:01:25:036 [HTTP]
2021-10-10 08:01:25:042 [HTTP] --> GET /wd/hub/session/b76bb00a-43bc-4155-bd6a-ccaa3eb865b2/contexts
2021-10-10 08:01:25:043 [HTTP] {}
2021-10-10 08:01:25:044 [W3C (b76bb00a)] Calling AppiumDriver.getContexts() with args: ["b76bb00a-43bc-4155-bd6a-ccaa3eb865b2"]
2021-10-10 08:01:25:047 [AndroidDriver] Getting a list of available webviews
2021-10-10 08:01:25:047 [ADB] Running '/Users/yujin/Library/Android/sdk/platform-tools/adb -P 5037 -s emulator-5554 shell cat /proc/net/unix'
2021-10-10 08:01:25:109 [AndroidDriver] Not checking whether webviews have active pages; use the 'ensureWebviewsHavePages' cap to turn this check on
2021-10-10 08:01:25:111 [AndroidDriver] WEBVIEW_2632 mapped to pid 2632
2021-10-10 08:01:25:112 [AndroidDriver] Getting process name for webview
2021-10-10 08:01:25:113 [ADB] Running '/Users/yujin/Library/Android/sdk/platform-tools/adb -P 5037 -s emulator-5554 shell ps'
2021-10-10 08:01:25:146 [AndroidDriver] Parsed pid: '2632' pkg: 'io.appium.android.apis' from
2021-10-10 08:01:25:147 [AndroidDriver] USER PID PPID VSIZE RSS WCHAN PC NAME
2021-10-10 08:01:25:147 [AndroidDriver] u0_a45 2632 291 1139548 124380 0 7f808082cc1a S io.appium.android.apis
2021-10-10 08:01:25:147 [AndroidDriver] Returning process name: 'io.appium.android.apis'
2021-10-10 08:01:25:148 [AndroidDriver] Found webviews: ["WEBVIEW_io.appium.android.apis"]
2021-10-10 08:01:25:148 [AndroidDriver] Available contexts: ["NATIVE_APP","WEBVIEW_io.appium.android.apis"]
2021-10-10 08:01:25:149 [W3C (b76bb00a)] Responding to client with driver.getContexts() result: ["NATIVE_APP","WEBVIEW_io.appium.android.apis"]
2021-10-10 08:01:25:154 [HTTP] <-- GET /wd/hub/session/b76bb00a-43bc-4155-bd6a-ccaa3eb865b2/contexts 200 108 ms - 57
2021-10-10 08:01:25:155 [HTTP]
2021-10-10 08:01:25:158 [HTTP] --> POST /wd/hub/session/b76bb00a-43bc-4155-bd6a-ccaa3eb865b2/context
2021-10-10 08:01:25:159 [HTTP] {"name":"WEBVIEW_io.appium.android.apis"}
2021-10-10 08:01:25:161 [W3C (b76bb00a)] Calling AppiumDriver.setContext() with args: ["WEBVIEW_io.appium.android.apis","b76bb00a-43bc-4155-bd6a-ccaa3eb865b2"]
2021-10-10 08:01:25:164 [AndroidDriver] Getting a list of available webviews
2021-10-10 08:01:25:165 [ADB] Running '/Users/yujin/Library/Android/sdk/platform-tools/adb -P 5037 -s emulator-5554 shell cat /proc/net/unix'
2021-10-10 08:01:25:186 [AndroidDriver] Not checking whether webviews have active pages; use the 'ensureWebviewsHavePages' cap to turn this check on
2021-10-10 08:01:25:187 [AndroidDriver] WEBVIEW_2632 mapped to pid 2632
2021-10-10 08:01:25:187 [AndroidDriver] Getting process name for webview
2021-10-10 08:01:25:188 [ADB] Running '/Users/yujin/Library/Android/sdk/platform-tools/adb -P 5037 -s emulator-5554 shell ps'
2021-10-10 08:01:25:223 [AndroidDriver] Parsed pid: '2632' pkg: 'io.appium.android.apis' from
2021-10-10 08:01:25:224 [AndroidDriver] USER PID PPID VSIZE RSS WCHAN PC NAME
2021-10-10 08:01:25:224 [AndroidDriver] u0_a45 2632 291 1139548 124380 0 7f808082cc1a S io.appium.android.apis
2021-10-10 08:01:25:224 [AndroidDriver] Returning process name: 'io.appium.android.apis'
2021-10-10 08:01:25:225 [AndroidDriver] Found webviews: ["WEBVIEW_io.appium.android.apis"]
2021-10-10 08:01:25:225 [AndroidDriver] Available contexts: ["NATIVE_APP","WEBVIEW_io.appium.android.apis"]
2021-10-10 08:01:25:226 [AndroidDriver] Connecting to chrome-backed webview context 'WEBVIEW_io.appium.android.apis'
2021-10-10 08:01:25:238 [AndroidDriver] A port was not given, using random free port: 8000
2021-10-10 08:01:25:239 [AndroidDriver] Automated Chromedriver download is disabled. Use 'chromedriver_autodownload' server feature to enable it
2021-10-10 08:01:25:239 [AndroidDriver] Before starting chromedriver, androidPackage is 'io.appium.android.apis'
2021-10-10 08:01:25:240 [Chromedriver] Changed state to 'starting'
2021-10-10 08:01:25:245 [Chromedriver] Found 1 executable in '/usr/local/lib/node_modules/appium/node_modules/appium-chromedriver/chromedriver/mac'
2021-10-10 08:01:25:294 [Chromedriver] The following Chromedriver executables were found:
2021-10-10 08:01:25:294 [Chromedriver] '/usr/local/lib/node_modules/appium/node_modules/appium-chromedriver/chromedriver/mac/chromedriver__mumu_2.42' (version '2.42', minimum Chrome version '68.0.3440')
2021-10-10 08:01:25:295 [ADB] Getting package info for 'com.google.android.webview'
2021-10-10 08:01:25:295 [ADB] Running '/Users/yujin/Library/Android/sdk/platform-tools/adb -P 5037 -s emulator-5554 shell dumpsys package com.google.android.webview'
2021-10-10 08:01:25:324 [ADB] Getting package info for 'com.android.webview'
2021-10-10 08:01:25:325 [ADB] Running '/Users/yujin/Library/Android/sdk/platform-tools/adb -P 5037 -s emulator-5554 shell dumpsys package com.android.webview'
2021-10-10 08:01:25:354 [Chromedriver] Found Chrome bundle 'com.android.webview' version '68.0.3440'
2021-10-10 08:01:25:357 [Chromedriver] Found 1 Chromedriver executable capable of automating Chrome '68.0.3440'.
2021-10-10 08:01:25:358 [Chromedriver] Choosing the most recent, '/usr/local/lib/node_modules/appium/node_modules/appium-chromedriver/chromedriver/mac/chromedriver__mumu_2.42'.
2021-10-10 08:01:25:358 [Chromedriver] If a specific version is required, specify it with the `chromedriverExecutable`desired capability.
2021-10-10 08:01:25:359 [Chromedriver] Set chromedriver binary as: /usr/local/lib/node_modules/appium/node_modules/appium-chromedriver/chromedriver/mac/chromedriver__mumu_2.42
2021-10-10 08:01:25:360 [Chromedriver] Killing any old chromedrivers, running: pkill -15 -f "/usr/local/lib/node_modules/appium/node_modules/appium-chromedriver/chromedriver/mac/chromedriver__mumu_2.42.*--port=8000"
2021-10-10 08:01:25:428 [Chromedriver] No old chromedrivers seem to exist
2021-10-10 08:01:25:428 [Chromedriver] Cleaning any old adb forwarded port socket connections
2021-10-10 08:01:25:429 [ADB] List forwarding ports
2021-10-10 08:01:25:429 [ADB] Running '/Users/yujin/Library/Android/sdk/platform-tools/adb -P 5037 -s emulator-5554 forward --list'
2021-10-10 08:01:25:441 [ADB] Removing forwarded port socket connection: 55916
2021-10-10 08:01:25:441 [ADB] Running '/Users/yujin/Library/Android/sdk/platform-tools/adb -P 5037 -s emulator-5554 forward --remove tcp:55916'
2021-10-10 08:01:25:456 [Chromedriver] Spawning chromedriver with: /usr/local/lib/node_modules/appium/node_modules/appium-chromedriver/chromedriver/mac/chromedriver__mumu_2.42 --url-base=wd/hub --port=8000 --adb-port=5037 --verbose
2021-10-10 08:01:25:477 [Chromedriver] Chromedriver version: '2.42.591059'
2021-10-10 08:01:25:478 [Chromedriver] Chromedriver v. 2.42.591059 does not fully support W3C protocol. Defaulting to MJSONWP
2021-10-10 08:01:25:479 [WD Proxy] Matched '/status' to command name 'getStatus'
2021-10-10 08:01:25:480 [WD Proxy] Proxying [GET /status] to [GET http://127.0.0.1:8000/wd/hub/status] with no body
2021-10-10 08:01:25:486 [WD Proxy] Got an unexpected response with status undefined: {"errno":-61,"code":"ECONNREFUSED","syscall":"connect","address":"127.0.0.1","port":8000}
2021-10-10 08:01:25:690 [WD Proxy] Matched '/status' to command name 'getStatus'
2021-10-10 08:01:25:691 [WD Proxy] Proxying [GET /status] to [GET http://127.0.0.1:8000/wd/hub/status] with no body
2021-10-10 08:01:25:704 [WD Proxy] Got response with status 200: {"sessionId":"","status":0,"value":{"build":{"version":"alpha"},"os":{"arch":"x86_64","name":"Mac OS X","version":"10.16.0"}}}
2021-10-10 08:01:25:705 [Chromedriver] Starting MJSONWP Chromedriver session with capabilities: {
2021-10-10 08:01:25:705 [Chromedriver] "desiredCapabilities": {
2021-10-10 08:01:25:706 [Chromedriver] "chromeOptions": {
2021-10-10 08:01:25:706 [Chromedriver] "androidPackage": "io.appium.android.apis",
2021-10-10 08:01:25:707 [Chromedriver] "androidUseRunningApp": true,
2021-10-10 08:01:25:708 [Chromedriver] "androidDeviceSerial": "emulator-5554"
2021-10-10 08:01:25:708 [Chromedriver] },
2021-10-10 08:01:25:708 [Chromedriver] "loggingPrefs": {
2021-10-10 08:01:25:709 [Chromedriver] "browser": "ALL"
2021-10-10 08:01:25:709 [Chromedriver] }
2021-10-10 08:01:25:709 [Chromedriver] }
2021-10-10 08:01:25:709 [Chromedriver] }
2021-10-10 08:01:25:710 [WD Proxy] Matched '/session' to command name 'createSession'
2021-10-10 08:01:25:711 [WD Proxy] Proxying [POST /session] to [POST http://127.0.0.1:8000/wd/hub/session] with body: {"desiredCapabilities":{"chromeOptions":{"androidPackage":"io.appium.android.apis","androidUseRunningApp":true,"androidDeviceSerial":"emulator-5554"},"loggingPrefs":{"browser":"ALL"}}}
2021-10-10 08:01:26:408 [Chromedriver] Webview version: 'Chrome/68.0.3440.70'
2021-10-10 08:01:26:542 [WD Proxy] Got response with status 200: {"sessionId":"ed7fb83742cae3d1847485e4a02ad001","status":0,"value":{"acceptInsecureCerts":false,"acceptSslCerts":false,"applicationCacheEnabled":false,"browserConnectionEnabled":false,"browserName":"chrome","chrome":{"chromedriverVersion":"2.42.591059 (a3d9684d10d61aa0c45f6723b327283be1ebaad8)"},"cssSelectorsEnabled":true,"databaseEnabled":false,"goog:chromeOptions":{"debuggerAddress":"localhost:57973"},"handlesAlerts":true,"hasTouchScreen":true,"javascriptEnabled":true,"locationContextEnabled":true,"mobileEmulationEnabled":false,"nativeEvents":true,"pageLoadStrategy":"normal","platform":"ANDROID","rotatable":false,"setWindowRect":false,"takesHeapSnapshot":true,"takesScreenshot":true,"unexpectedAlertBehaviour":"","version":"68.0.3440.70","webStorageEnabled":true}}
2021-10-10 08:01:26:543 [WD Proxy] Determined the downstream protocol as 'MJSONWP'
2021-10-10 08:01:26:543 [Chromedriver] Changed state to 'online'
2021-10-10 08:01:26:545 [W3C (b76bb00a)] Responding to client with driver.setContext() result: null
2021-10-10 08:01:26:547 [HTTP] <-- POST /wd/hub/session/b76bb00a-43bc-4155-bd6a-ccaa3eb865b2/context 200 1389 ms - 14
2021-10-10 08:01:26:548 [HTTP]
2021-10-10 08:01:26:549 [HTTP] --> GET /wd/hub/session/b76bb00a-43bc-4155-bd6a-ccaa3eb865b2/source
2021-10-10 08:01:26:550 [HTTP] {}
2021-10-10 08:01:26:551 [W3C (b76bb00a)] Driver proxy active, passing request on via HTTP proxy
2021-10-10 08:01:26:553 [WD Proxy] Matched '/wd/hub/session/b76bb00a-43bc-4155-bd6a-ccaa3eb865b2/source' to command name 'getPageSource'
2021-10-10 08:01:26:553 [WD Proxy] Proxying [GET /wd/hub/session/b76bb00a-43bc-4155-bd6a-ccaa3eb865b2/source] to [GET http://127.0.0.1:8000/wd/hub/session/ed7fb83742cae3d1847485e4a02ad001/source] with body: {}
2021-10-10 08:01:26:617 [WD Proxy] Got response with status 200: {"sessionId":"ed7fb83742cae3d1847485e4a02ad001","status":0,"value":"\u003C!DOCTYPE html>\u003Chtml xmlns="http://www.w3.org/1999/xhtml">\u003Chead>\n \u003Ctitle>I am a page title\u003C/title>\n\u003C/head>\n\u003Cbody>\n I am some other page content\n\n\n\u003Ciframe name="chromedriver dummy frame" src="about:blank">\u003C/iframe>\u003C/body>\u003C/html>"}
2021-10-10 08:01:26:618 [WD Proxy] Replacing sessionId ed7fb83742cae3d1847485e4a02ad001 with b76bb00a-43bc-4155-bd6a-ccaa3eb865b2
2021-10-10 08:01:26:620 [HTTP] <-- GET /wd/hub/session/b76bb00a-43bc-4155-bd6a-ccaa3eb865b2/source 200 70 ms - 305
2021-10-10 08:01:26:620 [HTTP]
2021-10-10 08:02:26:630 [BaseDriver] Shutting down because we waited 60 seconds for a command
2021-10-10 08:02:26:631 [UiAutomator2] Deleting UiAutomator2 session
2021-10-10 08:02:26:632 [Appium] Closing session, cause was 'New Command Timeout of 60 seconds expired. Try customizing the timeout using the 'newCommandTimeout' desired capability'
2021-10-10 08:02:26:633 [Appium] Removing session b76bb00a-43bc-4155-bd6a-ccaa3eb865b2 from our master session list
2021-10-10 08:02:26:633 [AndroidDriver] Stopping chromedriver for context WEBVIEW_io.appium.android.apis
2021-10-10 08:02:26:635 [Chromedriver] Changed state to 'stopping'
2021-10-10 08:02:26:644 [WD Proxy] Proxying [DELETE /] to [DELETE http://127.0.0.1:8000/wd/hub/session/ed7fb83742cae3d1847485e4a02ad001] with no body
2021-10-10 08:02:26:648 [WD Proxy] Got response with status 200: {"sessionId":"ed7fb83742cae3d1847485e4a02ad001","status":0,"value":null}
2021-10-10 08:02:26:653 [Chromedriver] Changed state to 'stopped'
2021-10-10 08:02:26:654 [UiAutomator2] Deleting UiAutomator2 server session
2021-10-10 08:02:26:654 [WD Proxy] Matched '/' to command name 'deleteSession'
2021-10-10 08:02:26:654 [WD Proxy] Proxying [DELETE /] to [DELETE http://localhost:8200/wd/hub/session/1f7ceff4-e731-4b38-b43f-7fde4ed9268a] with no body
2021-10-10 08:02:26:749 [WD Proxy] Got response with status 200: {"sessionId":"1f7ceff4-e731-4b38-b43f-7fde4ed9268a","value":null}
2021-10-10 08:02:26:749 [ADB] Running '/Users/yujin/Library/Android/sdk/platform-tools/adb -P 5037 -s emulator-5554 shell am force-stop io.appium.android.apis'
2021-10-10 08:02:27:454 [Instrumentation] .
2021-10-10 08:02:28:500 [Instrumentation] Time: 81.417
2021-10-10 08:02:28:501 [Instrumentation]
2021-10-10 08:02:28:502 [Instrumentation] OK (1 test)
2021-10-10 08:02:28:523 [Logcat] Stopping logcat capture
2021-10-10 08:02:28:525 [ADB] Removing forwarded port socket connection: 8200
2021-10-10 08:02:28:525 [ADB] Running '/Users/yujin/Library/Android/sdk/platform-tools/adb -P 5037 -s emulator-5554 forward --remove tcp:8200'
2021-10-10 08:02:28:762 [Instrumentation] The process has exited with code 0
WebView的内存泄漏怎么办?
1.不在xml中定义 Webview ,而是在需要的时候在Activity中创建,并且Context使用 getApplicationgContext()
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);mWebView = new WebView(getApplicationContext());mWebView.setLayoutParams(params);mLayout.addView(mWebView);
2.在 Activity 销毁( WebView )的时候,先让 WebView 加载null内容,然后移除 WebView,再销毁 WebView,最后置空。
@Override
protected void onDestroy() {if (mWebView != null) {mWebView.loadDataWithBaseURL(null, "", "text/html", "utf-8", null);mWebView.clearHistory();
((ViewGroup) mWebView.getParent()).removeView(mWebView);mWebView.destroy();mWebView = null;}super.onDestroy();
}
WebView的使用漏洞 及其修复方式
WebView中,主要漏洞有三类:
1.任意代码执行漏洞
2.密码明文存储漏洞
3.域控制不严格漏洞
(一)任意代码执行漏洞
- (1)addJavascriptInterface 接口引起远程代码执行漏洞
- 漏洞产生原因:
js调用Android的其中一个方式是通过addJavascriptInterface接口进行对象映射:
webView.addJavascriptInterface(new JSObject(), "myObj");// 参数1:Android的本地对象// 参数2:JS的对象// 通过对象映射将Android中的本地对象和JS中的对象进行关联,从而实现JS调用Android的对象和方法所以,漏洞产生原因是:当JS拿到android这个对象后,就可以调用这个Android对象中所有的方法,包括系统类(Java.lang.Runtime 类),
从而进行任意代码执行。(比如**我们可以执行命令获取本地设备的SD卡中的文件等信息从而造成信息泄露**)
具体获取系统类的描述:(结合 Java 反射机制)
- Android中的对象有一公共的方法:getClass() ;
- 该方法可以获取到当前类 类型Class
- 该类有一关键的方法: Class.forName;
- 该方法可以加载一个类(可加载 java.lang.Runtime 类)
- 而该类是可以执行本地命令的
以下是攻击的Js核心代码:
function execute(cmdArgs) { // 步骤1:遍历 window 对象// 目的是为了找到包含 getClass ()的对象// 因为Android映射的JS对象也在window中,所以肯定会遍历到for (var obj in window) { if ("getClass" in window[obj]) { // 步骤2:利用反射调用forName()得到Runtime类对象alert(obj); return window[obj].getClass().forName("java.lang.Runtime") // 步骤3:以后,就可以调用静态方法来执行一些命令,比如访问文件的命令getMethod("getRuntime",null).invoke(null,null).exec(cmdArgs); // 从执行命令后返回的输入流中得到字符串,有很严重暴露隐私的危险。// 如执行完访问文件的命令之后,就可以得到文件名的信息了。} }
}
当一些 APP 通过扫描二维码打开一个外部网页时,攻击者就可以执行这段 js 代码进行漏洞攻击。在微信盛行、扫一扫行为普及的情况下,该漏洞的危险性非常大
2.解决方法
Android 4.2版本之后:Google 在Android 4.2 版本中规定对被调用的函数以 @JavascriptInterface进行注解从而避免漏洞攻击
Android 4.2版本之前:采用拦截prompt()进行漏洞修复。 具体步骤如下:
1.继承 WebView ,重写 addJavascriptInterface 方法,然后在内部自己维护一个对象映射关系的 Map ( 将需要添加的 JS 接口放入该Map中 )
2.每次当 WebView 加载页面前加载一段本地的 JS 代码,原理是:1) 让JS调用一Javascript方法:该方法是通过调用prompt()把JS中的信息(含特定标识,方法名称等)传递到Android端;2) 在Android的onJsPrompt()中 ,解析传递过来的信息,再通过反射机制调用Java对象的方法,这样实现安全的JS调用Android代码。
关于Android返回给JS的值:可通过prompt()把Java中方法的处理结果返回到Js中
具体需要加载的JS代码如下:
javascript:(function JsAddJavascriptInterface_(){ // window.jsInterface 表示在window上声明了一个Js对象// jsInterface = 注册的对象名// 它注册了两个方法,onButtonClick(arg0)和onImageClick(arg0, arg1, arg2)// 如果有返回值,就添加上returnif (typeof(window.jsInterface)!='undefined') { console.log('window.jsInterface_js_interface_name is exist!!');} else { window.jsInterface = { // 声明方法形式:方法名: function(参数)onButtonClick:function(arg0) { // prompt()返回约定的字符串// 该字符串可自己定义// 包含特定的标识符MyApp和 JSON 字符串(方法名,参数,对象名等) return prompt('MyApp:'+JSON.stringify({obj:'jsInterface',func:'onButtonClick',args:[arg0]})); }, onImageClick:function(arg0,arg1,arg2) { return prompt('MyApp:'+JSON.stringify({obj:'jsInterface',func:'onImageClick',
args:[arg0,arg1,arg2]})); }, }; }
}
)()
// 当JS调用 onButtonClick() 或 onImageClick() 时,就会回调到Android中的 onJsPrompt ()
// 我们解析出方法名,参数,对象名
// 再通过反射机制调用Java对象的方法
关于采用拦截prompt()进行漏洞修复需要注意的两点细节:
细节1:加载上述JS代码的时机
由于当 WebView 跳转到下一个页面时,之前加载的 JS 可能已经失效,所以,通常需要在以下方法中加载js:onLoadResource();doUpdateVisitedHistory();onPageStarted();onPageFinished();onReceivedTitle();onProgressChanged();
细节2:需要过滤掉 Object 类的方法
由于最终是通过反射得到Android指定对象的方法,所以同时也会得到基类的其他方法(最顶层的基类是 Object类)
为了不把 getClass()等方法注入到 JS 中,我们需要把 Object 的共有方法过滤掉,需要过滤的方法列表如下:getClass()hashCode()notify()notifyAl()equals()toString()wait()
- (2)searchBoxJavaBridge_接口引起远程代码执行漏洞
- 产生原因
1) 在Android 3.0以下,Android系统会默认通过searchBoxJavaBridge_的Js接口给 WebView 添加一个JS映射对象:
searchBoxJavaBridge_对象
2) 该接口可能被利用,实现远程任意代码。
- 解决方法
删除searchBoxJavaBridge_接口
// 通过调用该方法删除接口removeJavascriptInterface();
- (3)accessibility和 accessibilityTraversal接口引起远程代码执行漏洞
- 产生原因
1) 在Android 3.0以下,Android系统会默认通过searchBoxJavaBridge_的Js接口给 WebView 添加一个JS映射对象:
searchBoxJavaBridge_对象
2) 该接口可能被利用,实现远程任意代码。
- 解决方法
删除searchBoxJavaBridge_接口
// 通过调用该方法删除接口removeJavascriptInterface();
(二)密码明文存储漏洞
- (1)问题分析
//WebView默认开启密码保存功能 :
mWebView.setSavePassword(true)
开启后,在用户输入密码时,会弹出提示框:询问用户是否保存密码;
如果选择”是”,密码会被明文保到 /data/data/com.package.name/databases/webview.db 中,这样就有被盗取密码的危险
- (2)解决方案
//关闭密码保存提醒
WebSettings.setSavePassword(false)
(三)域控制不严格漏洞
先看Android里的WebViewActivity.java:
public class WebViewActivity extends Activity {private WebView webView;public void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_webview);webView = (WebView) findViewById(R.id.webView);
//webView.getSettings().setAllowFileAccess(false); (1)//webView.getSettings().setAllowFileAccessFromFileURLs(true); (2)//webView.getSettings().setAllowUniversalAccessFromFileURLs(true); (3)Intent i = getIntent();String url = i.getData().toString(); //url = file:///data/local/tmp/attack.html webView.loadUrl(url);}}
/**Mainifest.xml**/
// 将该 WebViewActivity 在Mainifest.xml设置exported属性
// 表示:当前Activity是否可以被另一个Application的组件启动
android:exported="true"
- (1)问题分析
上述demo中:即 A 应用可以通过 B 应用导出的 Activity 让 B 应用加载一个恶意的 file 协议的 url,从而可以获取 B 应用的内部私有文件,从而带来数据泄露威胁 具体:当其他应用启动此 Activity 时, intent 中的 data 直接被当作 url 来加载(假定传进来的 url 为 file:///data/local/tmp/attack.html ),其他 APP 通过使用显式 ComponentName 或者其他类似方式就可以很轻松的启动该 WebViewActivity 并加载恶意url。 下面我们着重分析WebView中getSettings类的方法对 WebView 安全性的影响:
setAllowFileAccess()
setAllowFileAccessFromFileURLs()
setAllowUniversalAccessFromFileURLs()
- (2) setAllowFileAccess()
// 设置是否允许 WebView 使用 File 协议,默认设置为true,即允许在 File 域下执行任意 JavaScript 代码
webView.getSettings().setAllowFileAccess(true);
但是同时也限制了 WebView 的功能,使其不能加载本地的 html 文件,( 移动版的 Chrome 默认禁止加载 file 协议的文件 )
解决方案:
1) 对于不需要使用 file 协议的应用,禁用 file 协议;setAllowFileAccess(false); 2) 对于需要使用 file 协议的应用,禁止 file 协议加载 JavaScript。setAllowFileAccess(true); // 禁止 file 协议加载 JavaScriptif (url.startsWith("file://") {setJavaScriptEnabled(false);} else {setJavaScriptEnabled(true);}
- (3)setAllowFileAccessFromFileURLs()
设置是否允许通过 file url 加载的 Js代码读取其他的本地文件 , 在Android 4.1前默认允许 , 在Android 4.1后默认禁止
webView.getSettings().setAllowFileAccessFromFileURLs(true);
当AllowFileAccessFromFileURLs()设置为 true 时,攻击者的JS代码为 ( 通过该代码可成功读取 /etc/hosts 的内容数据 ) :
<script>function loadXMLDoc(){var arm = "file:///etc/hosts";var xmlhttp;if (window.XMLHttpRequest){xmlhttp=new XMLHttpRequest();}xmlhttp.onreadystatechange=function(){//alert("status is"+xmlhttp.status);if (xmlhttp.readyState==4){console.log(xmlhttp.responseText);}}xmlhttp.open("GET",arm);xmlhttp.send(null);}loadXMLDoc();
</script>
解决方案:
设置setAllowFileAccessFromFileURLs(false);
当设置成为 false 时,上述JS的攻击代码执行会导致错误,表示浏览器禁止从 file url 中的 JavaScript读取其它本地文件。
- (4) setAllowUniversalAccessFromFileURLs()
设置是否允许通过 file url 加载的 Javascript 可以访问其他的源(包括http、https等源),在Android 4.1前默认允许(setAllowFileAccessFromFileURLs()不起作用),在Android 4.1后默认禁止
webView.getSettings().setAllowUniversalAccessFromFileURLs(true);
当AllowFileAccessFromFileURLs()被设置成true时,攻击者的JS代码是:
// 通过该代码可成功读取 http://www.so.com 的内容
<script>function loadXMLDoc(){var arm = "http://www.so.com";var xmlhttp;if (window.XMLHttpRequest){xmlhttp=new XMLHttpRequest();}xmlhttp.onreadystatechange=function(){//alert("status is"+xmlhttp.status);if (xmlhttp.readyState==4){console.log(xmlhttp.responseText);}}xmlhttp.open("GET",arm);xmlhttp.send(null);}loadXMLDoc();
</script>
解决方案:
设置setAllowUniversalAccessFromFileURLs(false);
- (5) setJavaScriptEnabled()
设置是否允许 WebView 使用 JavaScript(默认是不允许),但很多应用(包括移动浏览器)为了让 WebView 执行 http 协议中的 JavaScript,都会主动设置为true,不区别对待是非常危险的,如下代码所示:
webView.getSettings().setJavaScriptEnabled(true);
即使把setAllowFileAccessFromFileURLs()和setAllowUniversalAccessFromFileURLs()都设置为 false,通过 file URL 加载的 javascript仍然有方法访问其他的本地文件:符号链接跨源攻击(前提是允许 file URL 执行 javascript,即webView.getSettings().setJavaScriptEnabled(true);)
原因分析:
这一攻击能奏效的原因是:通过 javascript 的延时执行和将当前文件替换成指向其它文件的软链接就可以读取到被符号链接所指的文件。
具体攻击步骤:(在该命令执行前 xx.html 是不存在的;执行完这条命令之后,就生成了这个文件,并且将 Cookie 文件链接到了 xx.html 上。) 1. 把恶意的 js 代码输出到攻击应用的目录下,随机命名为 xx.html,修改该目录的权限; 2. 修改后休眠 1s,让文件操作完成; 3. 完成后通过系统的 Chrome 应用去打开该 xx.html 文件 4. 等待 4s 让 Chrome 加载完成该 html,最后将该 html 删除,并且使用 ln -s 命令为 Chrome 的 Cookie 文件创建软连接, 于是就可通过链接来访问 Chrome 的 Cookie
注意事项:Google 没有进行修复,只是让Chrome 最新版本默认禁用 file 协议,所以这一漏洞在最新版的 Chrome 中并不存在。 但是,在日常大量使用 WebView 的App和浏览器,都有可能受到此漏洞的影响。通过利用此漏洞,容易出现数据泄露的危险 如果是 file 协议,禁用 javascript 可以很大程度上减小跨源漏洞对 WebView 的威胁。 但并不能完全杜绝跨源文件泄露。例:应用实现了下载功能,对于无法加载的页面,会自动下载到 sd 卡中;由于 sd 卡中的文件所有应用都可以访问,于是可以通过构造一个 file URL 指向被攻击应用的私有文件,然后用此 URL 启动被攻击应用的 WebActivity,这样由于该 WebActivity 无法加载该文件,就会将该文件下载到 sd 卡下面,然后就可以从 sd 卡上读取这个文件了
文末
- (6) 最终解决方案
1)对于不需要使用 file 协议的应用,禁用 file 协议;
// 禁用 file 协议;
webView.setAllowFileAccess(false);
webView.setAllowFileAccessFromFileURLs(false);
webView.setAllowUniversalAccessFromFileURLs(false);
2)对于需要使用 file 协议的应用,禁止 file 协议加载 JavaScript。
// 需要使用 file 协议
webView.setAllowFileAccess(true);
webView.setAllowFileAccessFromFileURLs(false);
webView. setAllowUniversalAccessFromFileURLs(false);
// 禁止 file 协议加载 JavaScript
if (url.startsWith("file://") {webView.setJavaScriptEnabled(false);
} else {webView.setJavaScriptEnabled(true);
}
相关文章:
webview的工作、内存泄漏、漏洞以及缓存机制原理原理+方案解决
分析一段appium的日志来分析webview的工作原理,文章尾部附有自动化脚本及完整日志: 解析: 获取上下文列表 服务端发送命令adb shell cat /proc/net/unix获取域套接字列表。那什么是域套接字呢? 域套接字:是unix系统里…...
BFD协议原理
BFD协议原理引入背景不使用BFD带来的问题OSPF感知慢VRRP产生次优路径BFD技术简介BFD会话建立方式和检测机制BFD会话建立过程BFD工作流程BFD的单臂回声BFD默认参数以及调整方法总结引入背景 随着网络应用的广泛部署,网络发生中断可能影响业务正常运行并造成重大损失…...
你把骑行当什么? 它就是你需要的
1.骑行是一种有活力的运动,尝试一下你一定会喜欢上它的!2.把骑行当作一种娱乐,让自己快乐地体验自然的美!3.骑行可以帮助你改变心态,让你的心情变得更加愉悦!4.让骑行成为你每天的计划,看看骑行…...
python基础系列 —— 迭代器与内置高阶函数
目录 一、迭代器 1、基本概念 2、如何定义一个迭代器 3、如果判断对象是否是迭代器 4、如何重置迭代器 5、如何调用迭代器 二、高阶函数 1、map函数 2、filter函数 3、reduce函数 4、sorted函数 一、迭代器 1、基本概念 迭代:是一个重复的过程,每次重复…...
MySQL面试题-日志
目录 1.MySQL 中常见的日志有哪些? 2.慢查询日志有什么用? 3.binlog 主要记录了什么? 4.Mysql的binlog有几种录入格式?分别有什么区别? 5.redo log 如何保证事务的持久性? 6.页修改之后为什么不直接刷…...
Android 10.0 去掉Launcher3默认给 icon增加的APK图标白边
1.概述 在10.0的系统产品开发中,Launcher3定制化开发中,发现在给第三方app的icon绘制图标的时候,会有白边第三方app的图标没有完全绘制出来,而系统app不存在这个问题,是完全绘制出来的,所以需要分析图标绘制类来解决这个问题 2.去掉Launcher3默认给 icon增加的APK图标白…...
E900V21C(S905L-armbian)安装armbian-Ubuntu(WiFi)
基本上是s905L芯片的刷机都是如此,包括Q7等 在网上寻找好多的教程关于e900v21c的刷机包和教程都少的可怜,唯一的就是这个:山东联通版创维E900V21C盒子刷入Armbiam并安装宝塔和Docker,但他是不能用WiFi和蓝牙的然后就是寻找s90l的…...
tpc协议的3次握手和4次挥手
建立连接的3次握手过程: A: 我想和你建立连接,你收到我的请求吗?(我想娶你) B: 好的,我收到了你的请求,我们可以建立连接,我同意。(好的,我愿意嫁给你) A: 好的,我收到了你的回应,我…...
YOLOv5害虫识别项目代码打包完整上传Gitee仓库(已开源)以及git上传速率限制踩坑记录
YOLOv5害虫识别项目代码打包完整上传Gitee仓库(已开源)以及git上传速率限制踩坑记录 ps: 最近很多小伙伴需要这个害虫识别项目的源码,由于文件过大,所以将代码完整上传至gitee,所有文件、教程、论文、以及代码模型…...
从零开始学习c语言|21、动态内存管理
一、malloc函数 1、什么是malloc函数 malloc是memery(内存)和allocate(分配)的缩写,顾名思义,malloc函数为动态分配内存的意思 2、malloc函数语句 int *p(int *)malloc(sizeof(int))malloc函数的形参为申请的内存空间大小,上述申请了一个i…...
swagger关闭/v2/api-docs仍然可以访问漏洞
今天接到安全团队的说swagger有未授权访问漏洞,即使在swagger关闭的情况下http://127.0.0.1:8086/agcloud/v2/api-docs?group%E7%94%A8%E6%88%B7%E5%85%B3%E8%81%94%E4%BF%A1%E6%81%AF%E6%A8%A1%E5%9D%97仍然还能访问。 看了下原来是有写一个拦截器 registry.addI…...
k8s pod调度总结
在Kubernetes平台上,我们很少会直接创建一个Pod,在大多数情况下会通过控制器完成对一组Pod副本的创建、调度 及全生命周期的自动控制任务,如:RC、Deployment、DaemonSet、Job 等。本文主要举例常见的Pod调度。1全自动调度功能&…...
28个案例问题分析---10---对生产环境的敬畏--生产环境
一:背景介绍 1:上午9:23,老师没有进行上课,但是却又很多的在线人员,并且在线人员的时间也不正确。 2:开发人员及时练习用户,查看用户上课情况。 3:10点整,询问项目组长发…...
视觉SLAM十四讲ch7-1视觉里程计笔记
视觉SLAM十四讲ch7-1 视觉里程计笔记本讲目标从本讲开始,开始介绍SLAM系统的重要算法特征点法ORB特征BRIEF实践特征提取与匹配2D-2D:对极几何八点法求E八点法的讨论从单应矩阵恢复R,t小结三角化。 符号读作*指向AA的指针(总在左侧)[]容纳AA的数组(总在左侧)()返…...
bash编程(马哥)
bash基础特性: 命令行展开:~,{} 命令别名:alias,unalias 命令历史:history 命令和路径补全:$PATH glob通配符:*,?,[],[^], 快捷键&am…...
搭建Gerrit环境Ubuntu
搭建Gerrit环境 1.安装apache sudo apt-get install apache2 注意:To run Gerrit behind an Apache server using mod_proxy, enable the necessary Apache2 modules: 执行:sudo a2enmod proxy_http 执行:sudo a2enmod ssl 使新的配置生效,需要执行如下命令:serv…...
朋友去华为面试,轻松拿到26K的Offer,羡慕了......
最近有朋友去华为面试,面试前后进行了20天左右,包含4轮电话面试、1轮笔试、1轮主管视频面试、1轮hr视频面试。 据他所说,80%的人都会栽在第一轮面试,要不是他面试前做足准备,估计都坚持不完后面几轮面试。 其实&…...
第25节 Node.js 断言测试
Node.js的assert模块主要用于编写程序的单元测试时使用,通过断言可以提早发现和排查出错误。 稳定性: 5 - 锁定 这个模块可用于应用的单元测试,通过 require(assert) 可以使用这个模块。 assert.fail(actual, expected, message, operator) 使用参数…...
【git】把本地更改提交远程新分支feature_g
创建并切换新分支 git checkout -b feature_g 添加并提交更改 git add . git commit -m “实现图片上传功能” 推送到远程 git push -u origin feature_g...
Spring数据访问模块设计
前面我们已经完成了IoC和web模块的设计,聪明的码友立马就知道了,该到数据访问模块了,要不就这俩玩个6啊,查库势在必行,至此,它来了。 一、核心设计理念 1、痛点在哪 应用离不开数据(数据库、No…...
精益数据分析(97/126):邮件营销与用户参与度的关键指标优化指南
精益数据分析(97/126):邮件营销与用户参与度的关键指标优化指南 在数字化营销时代,邮件列表效度、用户参与度和网站性能等指标往往决定着创业公司的增长成败。今天,我们将深入解析邮件打开率、网站可用性、页面参与时…...
C++:多态机制详解
目录 一. 多态的概念 1.静态多态(编译时多态) 二.动态多态的定义及实现 1.多态的构成条件 2.虚函数 3.虚函数的重写/覆盖 4.虚函数重写的一些其他问题 1).协变 2).析构函数的重写 5.override 和 final关键字 1&#…...
音视频——I2S 协议详解
I2S 协议详解 I2S (Inter-IC Sound) 协议是一种串行总线协议,专门用于在数字音频设备之间传输数字音频数据。它由飞利浦(Philips)公司开发,以其简单、高效和广泛的兼容性而闻名。 1. 信号线 I2S 协议通常使用三根或四根信号线&a…...
MySQL的pymysql操作
本章是MySQL的最后一章,MySQL到此完结,下一站Hadoop!!! 这章很简单,完整代码在最后,详细讲解之前python课程里面也有,感兴趣的可以往前找一下 一、查询操作 我们需要打开pycharm …...
k8s从入门到放弃之Pod的容器探针检测
k8s从入门到放弃之Pod的容器探针检测 在Kubernetes(简称K8s)中,容器探测是指kubelet对容器执行定期诊断的过程,以确保容器中的应用程序处于预期的状态。这些探测是保障应用健康和高可用性的重要机制。Kubernetes提供了两种种类型…...
Python爬虫(52)Scrapy-Redis分布式爬虫架构实战:IP代理池深度集成与跨地域数据采集
目录 一、引言:当爬虫遭遇"地域封锁"二、背景解析:分布式爬虫的两大技术挑战1. 传统Scrapy架构的局限性2. 地域限制的三种典型表现 三、架构设计:Scrapy-Redis 代理池的协同机制1. 分布式架构拓扑图2. 核心组件协同流程 四、技术实…...
多模态学习路线(2)——DL基础系列
目录 前言 一、归一化 1. Layer Normalization (LN) 2. Batch Normalization (BN) 3. Instance Normalization (IN) 4. Group Normalization (GN) 5. Root Mean Square Normalization(RMSNorm) 二、激活函数 1. Sigmoid激活函数(二分类&…...
