Solution to WebView unable to backoff and JS injection vulnerability in Android

Because the redirection cannot work normally, the goback() solution first talks about the problem. The initial page is a. click a link to jump to B( http://xxx.com.cn/ ), page B redirects to page C( http://xxx.com.cn/website/index.html )When WebView. Goback() is called, the page will fall back to B and then redirect back to C. This will cause two problems:

1. Unable to go back to the initial page of WebView a 2. Unable to exit activity or fragment normally (you can exit the page only if you go back before loading C)

As for how to solve this problem, I have summarized the following three methods, which can be used according to the specific situation: first, communicate with the front-end developers and pay attention to whether the orientation is necessary. If the jump link is only the domain name, and then redirect to the domain name / index.html by default without special treatment, then this redirection is meaningless. As long as the connection in the web page, such as

Directly replace with

This problem can be solved

2、 Redirection in the page is necessary, so we need to maintain a WebView history stack, filter, jump or reload the page according to our own needs: if we judge that the current link is reset backward, then when we go back, we need to ignore the previous link and do not use WebView. Goback() to remove the redirected and reset backward URL, After obtaining the initial page link, perform the loadurl () operation yourself

3. Another method, similar to method 2, needs to maintain the history stack of WebView, but needs the cooperation of the front end. It provides JS function to obtain whether the web page is redirected. When filtering the URL in the webviewclient callback shouldoverloading(), if it belongs to the redirected address, it will not be added to the stack. When backing out, it can be loaded according to the history stack

Here we mainly talk about method 2: first, define a history stack:

Add the initial page URL

Then add the loaded URL:

Finally, process in WebView. Goback():

As for the loading stack, it was later found that WebView itself also has a corresponding API:

However, this API may be affected by the system version or modified by different mobile phone systems, so when solving this problem, you can maintain the loaded history stack or call the system API directly according to your needs

To sum up, if redirection is not necessary, scheme 1 is the simplest and the amount of modification is very small. If redirection is necessary, scheme 2 or scheme 3 is used. Because it needs to interact with front-end personnel, the cost of communication, development and maintenance required by scheme 3 is much higher than that of scheme 2, but the judgment on whether to redirect is very accurate. If there are multiple redirections, After a development, there is no need to change the code again. Scheme 2 needs to write the URL to be filtered. If there are multiple redirects, the code will appear bloated, and the code needs to be added again every time. The specific use depends on the development situation in the project

Finally, a general method is added, but it needs strong support from the background: when the WebView is loaded, the request is sent to the server, and then the server analyzes and processes it, and returns the processed results to the client for display. In addition, the server can encode the web page content or take out redundancy, and improve the response speed in combination with CDN, This is also a common strategy for browser development at present. However, it requires a lot of data collection, analysis and processing, and is heavily dependent on the server. If the development progress is tight or the company's resources are limited, you can refer to the above methods first

The most important thing to say is that this article is mainly about the solution to the problems encountered in loading H5 developed by ourselves. As for the loading of third-party websites, there is no solution, including wechat. There is no general solution for various public platforms and third-party links, so they deal with them interactively, After a jump in H5, a close button will appear in the upper left corner of the title bar. After all, users do not know that they can normally return to the home page only by clicking twice in a row

JS object injection vulnerability solution 1. In the usage scenario, we often use WebView to display a web page. Now, in order to make the server controllable, many result pages are web pages rather than local implementation. This has many advantages. For example, the change of the interface does not need to republish a new version, but can be modified directly on the server. Using web pages to display interfaces usually interacts more or less with java code, such as clicking a button on the web page. We need to know the button click event, or we need to call a method to make the page perform some action. In order to realize these interactions, we usually use js, and WebView has provided such a method, The specific usage is as follows:

We register an object called "jsinterface" with WebView, and then we can access the jsinterface object in JS, call some methods of the object, and finally call it into Java code, so as to realize the interaction between JS and Java code. Let's take a look at the description of the addjavascriptinterface method on the Android official website: this method can be used to allow JavaScript to control the host application. This is a powerful feature, but also presents a security risk for applications targeted to API level Jerry_ BEAN or below,because JavaScript Could use reflection to access an injected object's public fields. Use of this method in a WebView containing untrusted content Could allow an attacker to manipulate the host application in unintended ways, executing Java code with the permissions of the host application. Use extreme care when using this method in a WebView which Could contain untrusted content. JavaScript interacts with Java object on a private, Background thread of this WebView. Care is thereforerequired to maintain thread safety. The Java object's fields are not accessible. The vulnerability we want to talk about today is this. When JS contains malicious code, it can do anything.

2. Vulnerability description through JavaScript, you can access anything on the SD card of the current device, even contact information, SMS, etc. It's disgusting, Gaga. OK, let's see how such a mistake happened. You can take a look at the bug description on the dark cloud platform: click here. 1. WebView adds JavaScript objects, and the current application has the permission to read and write sdcard, that is, android.permission.write_ EXTERNAL_ STORAGE 2, JS can traverse the window object, find the object that has the object of "getClass" method, then get the Runtime object through the mechanism of reflection, then call static method to execute some commands, such as access to the command of the file. 3, get the information of the file name after getting the string from the input stream returned after executing the command. Then do whatever you want. It's dangerous. The core JS code is as follows:

3. Example 1 of vulnerability proof: in order to prove this vulnerability, a demo is written to illustrate it. I just load a local web page containing malicious JS code. The HTML code is as follows:

The operation effect of this html is as follows:

Figure 1: expected operation results

In the figure above, after clicking the button, a text is passed to the Java code in JS to display a toast. After clicking the image, the URL, width and height of the image are transmitted to the Java layer and also displayed in toast. To achieve such a function, you need to note Java objects.

Simply explain 1, please look at the execute () method, which traverses all window objects, then finds objects containing getClass methods, uses the class of this object, finds java.lang.Runtime objects, then calls "getRuntime" static method to get instances of Runtime, and then calls exec () method to execute a certain command. 2. The getcontents () method reads the content from the stream and displays it on the interface. 3. The key code is the following two sentences

The Java code is implemented as follows:

Permissions to add:

After clicking the load menu, the operation screenshot is as follows: (in theory, figure 1 interface should appear)

Figure 2: actual operation results, listing the files in the sdcard

Example 2: 360 browser also has this problem. The system I tested is Android 4.0.2360. The browser version is 4.8.7. Enter in the browser input box: http://bitkiller.duapp.com/jsobj.html , then go to, and the following interface will appear

Figure 3: description of 360 browser operation results search@R_ 452_ 2419@JavaBridge_ It is not an object injected by 360, but injected internally by WebView, which was added on Android system after 3.0.

After closing this dialog box, it will list all the files on the current sdcard, as shown in the following figure

Figure 4: error results

4. Solution (1). For systems above Android 4.2, Google has made a correction by declaring a @ javascriptinterface on the Java Remote method, as shown in the following code:

(2) , this problem is difficult to solve for systems below Android 4.2, but it is not impossible to solve. First, we definitely can't call the addjavascriptinterface method anymore. The core of this problem is to know the action of JS event. JS interacts with Java. We know that there are several actions, such as prompt and alert. Such actions will correspond to the corresponding methods in webchromeclient class. For prompt, its corresponding method is onjsprompt method. The declaration of this method is as follows:

Through this method, JS can transfer information (text) to Java, and Java can also transfer information (text) to JS. Inform this idea. Can we find a solution? After some attempt and analysis, we found a more feasible scheme. Please see the following points: [1] let JS call a JavaScript method. In this method, we call the prompt method to pass the information in JS through prompt. These information should be a meaningful text we combined, which may include: specific identification, method name, parameters, etc. In the onjsprompt method, we parse the passed text, get the method name, parameters, etc., and then call the specified method through the reflection mechanism, so as to call the method of Java object. 【2】 The return value can be returned through prompt, so that the processing results of methods in Java can be returned to JS. 【3】 We need to dynamically generate a JS script that declares JavaScript methods, load it through loadurl, and register it in the HTML page. The specific code is as follows:

Note: [1]. The jsinterface in the above code is the object name to be registered. It registers two methods, onbuttonclick (arg0) and onimageclick (arg0, arg2). If there is a return value, add return. 【2】 , prompt is our agreed string, which contains the specific identifier myapp:, followed by a string of JSON strings, including method name, parameter, object name, etc. 【3】 , when JS calls onbuttonclick or onimageclick, it will call back to the onjsprompt method in the Java layer. We will resolve the method name, parameter and object name, and then reflect the calling method. 【4】 , window.jsinterface, which means that a JS object is declared on the window in the form of method name: function (parameter 1, parameter 2)

5. Some thoughts. The following are some problems and thoughts encountered in the implementation of this solution: (1) after generating the JS method, what is the time to load this JS? At the beginning, load the JS after WebView normally loads the URL, but it is found that there will be problems. If WebView jumps to the next page, the previously loaded JS may be invalid, so it needs to be loaded again. After trying this problem, you need to load JS in the following methods: webchromeclient and webviewclient:

(2) You need to filter out the methods of the object class. Because you get the methods of the specified object in the form of reflection, you will also get the methods of the base class. The top-level base class is object. Therefore, in order not to inject the getClass method into JS, you need to filter out the public methods of the object. Strictly speaking, there should be a list of filtering methods. In my current implementation, the methods to be filtered are:

(3) Load a section of JS by manually loadurl. Isn't the object in JS in the window in this way? That is, can't we find the JS object we injected through loadurl by traversing the window object? On this issue, our method is declared through JS and injected into the page in the form of loadurl. In fact, it is equivalent to writing this dynamically generated JS directly into the HTML page. Therefore, although the windows in these JS contain the objects declared by us, they are not Java objects. They are declared through JS syntax, Therefore, there is no method such as getClass. They are essentially JS objects.

(4) Under Android 3.0, the system has added a search@R_ 452_ 2419@JavaBridge_ To solve this security problem, we also need to delete this interface and call the removejavascriptinterface method. this search@R_ 452_ 2419@JavaBridge_ It seems to be related to Google's search box.

(5) In the implementation process, we need to judge whether the system version is below 4.2, because Android fixes this security problem above 4.2. We just need to fix the systems below 4.2.

The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>