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 | } -------------------------------------------------------------------------------- /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/java/android/webkit/safe/sample/WebActivity.java: -------------------------------------------------------------------------------- 1 | package android.webkit.safe.sample; 2 | 3 | import android.app.Activity; 4 | import android.content.Context; 5 | import android.content.Intent; 6 | import android.os.Bundle; 7 | import android.webkit.JsPromptResult; 8 | import android.webkit.WebSettings; 9 | import android.webkit.WebView; 10 | import android.webkit.WebViewClient; 11 | import android.webkit.safe.SafeWebView; 12 | 13 | public class WebActivity extends Activity { 14 | public static final String HTML = "file:///android_asset/test.html"; 15 | 16 | @Override 17 | public void onCreate(Bundle savedInstanceState) { 18 | super.onCreate(savedInstanceState); 19 | WebView webView = new InnerWebView(this); 20 | 21 | setContentView(webView); 22 | 23 | webView.loadUrl(HTML); 24 | } 25 | 26 | private class InnerWebView extends SafeWebView { 27 | 28 | public InnerWebView(Context context) { 29 | super(context); 30 | 31 | WebSettings ws = getSettings(); 32 | ws.setJavaScriptEnabled(true); 33 | addJavascriptInterface(new JavaScriptInterface(this), "Android"); 34 | setWebChromeClient(new InnerWebChromeClient()); 35 | setWebViewClient(new InnerWebViewClient()); 36 | } 37 | 38 | public class InnerWebChromeClient extends SafeWebChromeClient { 39 | 40 | @Override 41 | public void onProgressChanged (WebView view, int newProgress) { 42 | super.onProgressChanged(view, newProgress); // 务必放在方法体的第一行执行; 43 | // to do your work 44 | // ... 45 | } 46 | 47 | @Override 48 | public boolean onJsPrompt(WebView view, String url, String message, String defaultValue, JsPromptResult result) { 49 | // to do your work 50 | // ... 51 | return super.onJsPrompt(view, url, message, defaultValue, result); // 务必放在方法体的最后一行执行,或者用if判断也行; 52 | } 53 | } 54 | 55 | private class InnerWebViewClient extends WebViewClient { 56 | @Override 57 | public boolean shouldOverrideUrlLoading(WebView view, String url) { 58 | if (url.equals(UnsafeWebActivity.HTML)) { 59 | view.getContext().startActivity(new Intent(view.getContext(), UnsafeWebActivity.class)); 60 | return true; 61 | } 62 | return super.shouldOverrideUrlLoading(view, url); 63 | } 64 | } 65 | } 66 | } -------------------------------------------------------------------------------- /sample/src/main/res/drawable-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0xr0ot/SafeWebView/4ddd6345b1c7b94b89c6dd17f229b1729b4c1e78/sample/src/main/res/drawable-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /sample/src/main/res/drawable-ldpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0xr0ot/SafeWebView/4ddd6345b1c7b94b89c6dd17f229b1729b4c1e78/sample/src/main/res/drawable-ldpi/ic_launcher.png -------------------------------------------------------------------------------- /sample/src/main/res/drawable-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0xr0ot/SafeWebView/4ddd6345b1c7b94b89c6dd17f229b1729b4c1e78/sample/src/main/res/drawable-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /sample/src/main/res/drawable-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0xr0ot/SafeWebView/4ddd6345b1c7b94b89c6dd17f229b1729b4c1e78/sample/src/main/res/drawable-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /sample/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 |