hilbert / hilbert-docker-images

Application with a dynamic choice of docker containers to run
Apache License 2.0
22 stars 8 forks source link

Harden electron kiosk against script injection #18

Closed porst17 closed 8 years ago

porst17 commented 8 years ago

Electron is a very powerful framework for building desktops using web technologies. The web page that's displayed in electron basically has full control over the host or container, electron is running on. We actually only want use electron to build a hardened kiosk system and don't to take advantage of it's powerful (and dangerous) features.

Electron allows guest content to be wrapped into <webview> tags for sandboxing: https://github.com/atom/electron/blob/master/docs/api/web-view-tag.md

All the powerful node.js functionality can be disabled this way.

malex984 commented 8 years ago

Hm, yes we should try to prevent user content to interact with electron framework in kiosk mode.

porst17 commented 8 years ago

I think it should suffice to replace the current index.html with a wrapper index.html that just puts the content into a <webview> tag. Something like

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <script>
            document.body.onload = function() {
                webview = document.createElement( 'webview ' );
                webview.style.width = '100%';
                webview.style.height = '100%';
                webview.style.display = 'inline-block';

                // go to the url that's passed as a URL parameter via main.js:
                // index.html?the_encoded_url
                webview.src = decodeURI( window.location.search.substr(1) );

                // add the webview to the document
                document.body.appendChild( webview );
            };
        </script>
    </head>
    <body>
    </body>
</html>

The above code is untested, though. But the final result should very similar. The only minor drawback I see is that the window title will not match the title of the guest page. But I think we can ignore that. The title is not visible in full-screen mode anyway.

Maybe some additional CSS code is needed to make the <webview> cover the full page in any case. Has to be tested.

porst17 commented 8 years ago

Maybe something like

setInterval( function() { document.title = webview.getTitle(); }, 1000 );

can be used as a workaround to update title every second.

You would also need to update the menu of the kiosk browser: back button, developer tools etc have to affect the <webview>, not the main frame.

porst17 commented 8 years ago

It turned out to be way easier: all the necessary settings can be added as a parameter to the BrowserWindow via web-preferences. No need for this ugly indirection via <webview>.

At least nodeIntegration has to be set to false on the browser window. Maybe additional setting are needed. We have to check that: https://github.com/atom/electron/blob/master/docs/api/browser-window.md

malex984 commented 8 years ago

Fixed with d5d57d08f89e9778e1d58356c86e1a15cf63c336