Electron Webviewのセキュリティで注意すべきこと


こんにちは。プレイドのRyosukeです。現在、明治大学総合数理学部現象数理学科3年生で統計学系の研究室にいます。

今回は、Electron Webviewのセキュリティ面で注意すべきことを書きます。

Electron

Electronとはweb techでクロスプラットフォームデスクトップアプリを作ることができるものです。どういうアプリがElectronで作られてるのかはAwesome electronを御覧ください。

Electronは、nodejsをバックで動かし、chromiumブラウザ上でウェブページを表示することでデスクトップアプリを表現しています。Electronでは、nodejs側のjsプロセス(メインプロセス)とブラウザ側のjsプロセス(レンダラープロセス)は別になるため、プロセス間の通信手段としてipc (internal procedure call?)を使用します。

また、ブラウザ側では<webview>というhtmlタグを使用することができます。webviewとはiframeのように別のwebページをurlを指定することで表示するものです。ただ、iframeと違う部分があり、それは、webview内のjsプロセスはブラウザのjsプロセスとは別のインスタンスをもつということです。もちろん、webview内のjsプロセスはブラウザと同様にレンダラープロセスなので、メインプロセスとの通信手段を持ちます。ここに、セキュリティ面で注意すべきことがあります。

Webviewのセキュリティ

webviewのレンダラープロセスとメインプロセス間で通信をする必要がないのであれば問題はありませんが、それをしたかったり、webviewのレンダラープロセスでnodejsのAPIをrequireして使用したい場合はセキュリティ面で注意が必要です。

安全じゃない方法 - nodeintegration

<webview>のアトリビュートにはnodeintegrationというものがあります。これは、デフォルトではfalseになっていますが、明示的に指定することで、webview内でnodejsのrequireやprocessといった低レベルなシステムへのアクセスが許されます。webviewとメインプロセス間の通信にはipcをrequireする必要があるので、それをしたいのであれば、webviewにnodeintegrationをつけるのが手っ取り早いです。

しかし、XSSの危険性があり悪意のあるサイトが色々と悪さをできてしまいます。ですので、必ずnodeintegrationfalseになっていることを確認してください。

安全な方法 - preload

では、どうすればwebview内でipcや他のapiを使うことができるのでしょう。実はpreloadアトリビュートにjsファイルパスを指定することで、そのjsをpreloadすることができます。また、そのpreloadされるjsには制限が無いのでrequireをすることができますし、preload内のスコープはセキュリティ上、webview内のスコープとは別になるので、ある程度は安心できます。このpreloadを上手く使用することで、nodeintegrationがfalseなwebview内でも使用したいnodejs apiを使用できます。

renderer.html
<webview preload="PATH/TO/PREALOD_JS" src="URL">
preload.js
const {ipcRenderer} = require('electron')

global.sendToHost = (message) => {
  ipcRenderer.sendToHost(message)
}

他に読むべきもの