├── settings.gradle
├── app-sample-screenshot.png
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── sample
├── src
│ └── main
│ │ ├── res
│ │ ├── drawable-hdpi
│ │ │ └── ic_launcher.png
│ │ ├── drawable-ldpi
│ │ │ └── ic_launcher.png
│ │ ├── drawable-mdpi
│ │ │ └── ic_launcher.png
│ │ ├── drawable-xhdpi
│ │ │ └── ic_launcher.png
│ │ └── values
│ │ │ └── strings.xml
│ │ ├── AndroidManifest.xml
│ │ ├── assets
│ │ ├── unsafe_test.html
│ │ └── test.html
│ │ └── java
│ │ └── android
│ │ └── webkit
│ │ └── safe
│ │ └── sample
│ │ ├── JavaScriptInterface.java
│ │ ├── UnsafeWebActivity.java
│ │ └── WebActivity.java
├── proguard-android.txt
└── build.gradle
├── library
├── doc
│ ├── notRepeat.js
│ └── injected.js
├── src
│ └── main
│ │ ├── AndroidManifest.xml
│ │ └── java
│ │ └── android
│ │ └── webkit
│ │ └── safe
│ │ ├── LogUtils.java
│ │ ├── JsCallback.java
│ │ ├── JsCallJava.java
│ │ ├── WebViewProxySettings.java
│ │ └── SafeWebView.java
└── build.gradle
├── .gitignore
├── gradlew.bat
├── README.md
└── gradlew
/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':library', 'sample'
--------------------------------------------------------------------------------
/app-sample-screenshot.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seven456/SafeWebView/HEAD/app-sample-screenshot.png
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seven456/SafeWebView/HEAD/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/sample/src/main/res/drawable-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seven456/SafeWebView/HEAD/sample/src/main/res/drawable-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/sample/src/main/res/drawable-ldpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seven456/SafeWebView/HEAD/sample/src/main/res/drawable-ldpi/ic_launcher.png
--------------------------------------------------------------------------------
/sample/src/main/res/drawable-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seven456/SafeWebView/HEAD/sample/src/main/res/drawable-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/sample/src/main/res/drawable-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seven456/SafeWebView/HEAD/sample/src/main/res/drawable-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/sample/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
WebView漏洞测试(Android4.2.2以下版本可测)-(ls -l /mnt/sdcard/)
45 | 46 | 47 | -------------------------------------------------------------------------------- /sample/src/main/java/android/webkit/safe/sample/JavaScriptInterface.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Summary: js脚本所能执行的函数空间 3 | * Version 1.0 4 | * Date: 13-11-20 5 | * Time: 下午4:40 6 | * Copyright: Copyright (c) 2013 7 | */ 8 | 9 | package android.webkit.safe.sample; 10 | 11 | import android.os.Handler; 12 | import android.os.Looper; 13 | import android.webkit.WebView; 14 | import android.widget.Toast; 15 | 16 | import android.webkit.safe.JsCallback; 17 | 18 | public class JavaScriptInterface { 19 | private WebView mWebView; 20 | 21 | public JavaScriptInterface(WebView webView) { 22 | mWebView = webView; 23 | } 24 | 25 | /** 26 | * 短暂气泡提醒 27 | * 28 | * @param message 提示信息 29 | */ 30 | @android.webkit.JavascriptInterface 31 | public void toast(String message) { 32 | Toast.makeText(mWebView.getContext(), message, Toast.LENGTH_SHORT).show(); 33 | } 34 | 35 | /** 36 | * 弹出记录的测试JS层到Java层代码执行损耗时间差 37 | * 38 | * @param timeStamp js层执行时的时间戳 39 | */ 40 | @android.webkit.JavascriptInterface 41 | public void testLossTime(long timeStamp) { 42 | timeStamp = System.currentTimeMillis() - timeStamp; 43 | toast(String.valueOf(timeStamp)); 44 | } 45 | 46 | @android.webkit.JavascriptInterface 47 | public void delayJsCallBack(final int ms, final String backMsg, final JsCallback jsCallback) { 48 | new Handler(Looper.getMainLooper()).postDelayed(new Runnable() { 49 | @Override 50 | public void run() { 51 | try { 52 | jsCallback.apply(backMsg); 53 | } catch (JsCallback.JsCallbackException je) { 54 | je.printStackTrace(); 55 | } 56 | } 57 | }, ms); 58 | } 59 | } -------------------------------------------------------------------------------- /library/doc/injected.js: -------------------------------------------------------------------------------- 1 | (function(b) { 2 | console.log("Android initialization begin"); 3 | var a = { 4 | queue: [], 5 | callback: function() { 6 | var d = Array.prototype.slice.call(arguments, 0); 7 | var c = d.shift(); 8 | var e = d.shift(); 9 | this.queue[c].apply(this, d); 10 | if (!e) { 11 | delete this.queue[c] 12 | } 13 | } 14 | }; 15 | a.delayJsCallBack = a.testLossTime = a.toast = function() { 16 | var f = Array.prototype.slice.call(arguments, 0); 17 | if (f.length < 1) { 18 | throw "Android call error, message:miss method name" 19 | } 20 | var e = []; 21 | for (var h = 1; h < f.length; h++) { 22 | var c = f[h]; 23 | var j = typeof c; 24 | e[e.length] = j; 25 | if (j == "function") { 26 | var d = a.queue.length; 27 | a.queue[d] = c; 28 | f[h] = d 29 | } 30 | } 31 | var k = new Date().getTime(); 32 | var l = f.shift(); 33 | var m = prompt('SafeWebView: ' + JSON.stringify({method: l, types: e, args: f})); 34 | console.log("invoke " + l + ", time: " + (new Date().getTime() - k)); 35 | var g = JSON.parse(m); 36 | if (g.code != 200) { 37 | throw "Android call error, code:" + g.code + ", message:" + g.result 38 | } 39 | return g.result 40 | }; 41 | Object.getOwnPropertyNames(a).forEach(function(d) { 42 | var c = a[d]; 43 | if (typeof c === "function" && d !== "callback") { 44 | a[d] = function() { 45 | return c.apply(a, [d].concat(Array.prototype.slice.call(arguments, 0))) 46 | } 47 | } 48 | }); 49 | b.Android = a; 50 | console.log("Android initialization end") 51 | })(window) -------------------------------------------------------------------------------- /sample/src/main/java/android/webkit/safe/sample/UnsafeWebActivity.java: -------------------------------------------------------------------------------- 1 | package android.webkit.safe.sample; 2 | 3 | import android.app.Activity; 4 | import android.app.AlertDialog; 5 | import android.content.DialogInterface; 6 | import android.os.Bundle; 7 | import android.webkit.JsResult; 8 | import android.webkit.WebChromeClient; 9 | import android.webkit.WebSettings; 10 | import android.webkit.WebView; 11 | 12 | public class UnsafeWebActivity extends Activity { 13 | public static final String HTML = "file:///android_asset/unsafe_test.html"; 14 | 15 | @Override 16 | public void onCreate(Bundle savedInstanceState) { 17 | super.onCreate(savedInstanceState); 18 | WebView wv = new WebView(this); 19 | setContentView(wv); 20 | 21 | WebSettings webView = wv.getSettings(); 22 | webView.setJavaScriptEnabled(true); 23 | wv.setWebChromeClient(new InnerChromeClient()); 24 | 25 | wv.loadUrl(HTML); 26 | } 27 | 28 | public class InnerChromeClient extends WebChromeClient { 29 | 30 | @Override 31 | public boolean onJsAlert(WebView view, String url, String message, final JsResult result) { 32 | new AlertDialog.Builder(view.getContext()) 33 | .setMessage(message) 34 | .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() { 35 | @Override 36 | public void onClick(DialogInterface dialog, int which) { 37 | result.confirm(); 38 | } 39 | }) 40 | .setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() { 41 | @Override 42 | public void onClick(DialogInterface dialog, int which) { 43 | result.cancel(); 44 | } 45 | }) 46 | .create() 47 | .show(); 48 | return true; 49 | } 50 | } 51 | } -------------------------------------------------------------------------------- /sample/src/main/assets/test.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 |