Abstract
Currently ZeroNet uses a wrapper for sidebar and notifications UI, and embeds site content with an iframe. This proposal fixes some issues caused by iframing by embedding ZeroNet UI into site content.
Rationale
Add blob: scheme to Content-Security-Policy #2165 , Allow Pointer Lock API in iframe #2057 - All features have to be marked unsafe by default, so supporting new ones is troublesome;
Allow a site to bust out of IFrame #2154 - Most people don't understand what NOSANDBOX means;
Chrome is going to block interactive content in iframes #2086 - Some interactive content in iframes might get blocked;
Disable pull to refresh on all sites. #2058 - Pull-to-refresh is working weird with iframes;
"Opened as child-window, stopping..." #2003 - "Opening as child window" is sometimes impossible to bypass;
Open link in new tab really doesn't works #1736 - Opening link in a new tab is more difficult than required;
Picture in picture mode #1707 , Embedding other sites with iframes #565 - Embedding a site into a site is unsafe with an iframe;
API for change browser's header/address bar color #1667 - Browser header style can only be set by root frame;
Can't scroll in safari #1403 - Scrolling is impossible, iframe is most likely the reason;
How to use localStorage? #1399 , Accessing localStorage from zite #1054 , Allow sites to use localresources, IndexedDB, WebSql, etc #29 - localStorage, IndexedDB, etc. are not available in sandboxed iframes;
I make a WebGl game based on Unity3d. Then I put these files under my websites folder (clear all original files). When I open my web through ZeroNet, it just show nothing. #1237 - Fullscreen API doesn't work;
Error: Permission denied to access property "document" #1236 , Allow zite loading outside iframe (for zite owners) #1262 - Some Vue plugins don't work;
Sandbox prevents creating web worker #1010 - Creating Web Workers requires data: URI usage;
Uncaught SecurityError: #469 - History management requires ZeroFrame usage.
Overview
Current architecture:
┌─────────────────────────────────────────────────────┐
│ WRAPPER (src/Ui/template/wrapper.html) │
│ Stores secrets (e.g. wrapper key) │
│ ┌─────────────────────────────────────────────────┐ │
│ │ WS UPLINK │ │
│ │ UiWebsocket API │ │
│ └─────────────────────────────────────────────────┘ │
│ ┌─────────────────────────────────────────────────┐ │
│ │ NOTIFICATIONS (<div>) │ │
│ │ ╔═════════════════════════════════════════════╗ │ │
│ │ ║ SITE NOTIFICATIONS (<div>) ║ │ │
│ │ ║ Unsafe content (possible XSS) ║ │ │
│ │ ╚═════════════════════════════════════════════╝ │ │
│ │ ┌─────────────────────────────────────────────┐ │ │
│ │ │ WRAPPER NOTIFICATIONS (<div>) │ │ │
│ │ │ Safe content (no leaking or spoofing) │ │ │
│ │ └─────────────────────────────────────────────┘ │ │
│ └─────────────────────────────────────────────────┘ │
│ ┌─────────────────────────────────────────────────┐ │
│ │ SIDEBAR (<div>) │ │
│ │ Site and key management, safe │ │
│ │ ╔═════════════════════════════════════════════╗ │ │
│ │ ║ SITE DATA ║ │ │
│ │ ║ Title, description, donate links, etc. ║ │ │
│ │ ╚═════════════════════════════════════════════╝ │ │
│ └─────────────────────────────────────────────────┘ │
│ ╔═════════════════════════════════════════════════╗ │
│ ║ IFRAME SANDBOX ║ │
│ ║ Unsafe content (managed by site code) ║ │
│ ╚═════════════════════════════════════════════════╝ │
└─────────────────────────────────────────────────────┘
Safety layers are separated with double border.
No software has zero bugs. This includes security issues. There are many possible attack points here:
Site notifications (protected by manual escaping) were exploited by me, revealing site private keys;
Sidebar content (protected by manual escaping) wasn't exploited according to my sources, but it's still a valid point of attack;
Iframe sandbox (protected by browser) is in theory unbreakable, but still adds unnecessary complexity;
The final attack point is the external iframe (in case the wrapper is in an iframe itself). This was exploited by me once.
Proposed architecture;
┌─────────────────────────────────────────────────────┐
│ HTML PAGE │
│ ┌─────────────────────────────────────────────────┐ │
│ │ PREFIX (shadow DOM) │ │
│ │ Practically invisible to site content │ │
│ │ ┌─────────────────────────────────────────────┐ │ │
│ │ │ SITE NOTIFICATIONS (<div>) │ │ │
│ │ │ Unsafe content (possible XSS) │ │ │
│ │ └─────────────────────────────────────────────┘ │ │
│ │ ╔═════════════════════════════════════════════╗ │ │
│ │ ║ WRAPPER NOTIFICATIONS (<iframe>) ║ │ │
│ │ ║ Safe content (no leaking or spoofing) ║ │ │
│ │ ╚═════════════════════════════════════════════╝ │ │
│ │ ╔═════════════════════════════════════════════╗ │ │
│ │ ║ SIDEBAR (iframe) ║ │ │
│ │ ║ Site and key management ║ │ │
│ │ ║ ╔═════════════════════════════════════════╗ ║ │ │
│ │ ║ ║ GATE (iframe) ║ ║ │ │
│ │ ║ ║ ┌─────────────────────────────────────┐ ║ ║ │ │
│ │ ║ ║ │ WS UPLINK │ ║ ║ │ │
│ │ ║ ║ │ UiWebsocket API (ADMIN) │ ║ ║ │ │
│ │ ║ ║ └─────────────────────────────────────┘ ║ ║ │ │
│ │ ║ ╚═════════════════════════════════════════╝ ║ │ │
│ │ ╚═════════════════════════════════════════════╝ │ │
│ │ ╔═════════════════════════════════════════════╗ │ │
│ │ ║ GATE (iframe) ║ │ │
│ │ ║ ┌─────────────────────────────────────────┐ ║ │ │
│ │ ║ │ WS UPLINK │ ║ │ │
│ │ ║ │ UiWebsocket API (site) │ ║ │ │
│ │ ║ └─────────────────────────────────────────┘ ║ │ │
│ │ ╚═════════════════════════════════════════════╝ │ │
│ └─────────────────────────────────────────────────┘ │
│ ┌─────────────────────────────────────────────────┐ │
│ │ SITE DATA │ │
│ │ Unsafe content (managed by site code) │ │
│ └─────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────┘
Sure, it might look more difficult at the first glance, but security comes with a cost.
Resulting HTML
The resulting HTML (the one that browser receives) consists of a prefix and the real site .html file.
Prefix
Prefix is a "magic" HTML code that sets up an analogue of what was a wrapper by creating a shadow DOM node. This ensures that the sidebar and notifications are shown correctly, independent of main site styles, and that it doesn't affect the site itself.
Gate
A gate is an iframe that acts like a gate between UiWebsocket and its user. The gate handler uses the referrer to check what permissions the websocket must have.
Fixed issues / added features
Add blob: scheme to Content-Security-Policy #2165 , Allow Pointer Lock API in iframe #2057 - All features are now safe;
Allow a site to bust out of IFrame #2154 - No need for NOSANDBOX anymore;
Chrome is going to block interactive content in iframes #2086 - The only interactive content is simple notifications (i.e. buttons);
Disable pull to refresh on all sites. #2058 - Pull-to-refresh can now be controlled by the site;
"Opened as child-window, stopping..." #2003 - No need to be top frame anymore;
Open link in new tab really doesn't works #1736 - Opening in a new tab made easy;
Picture in picture mode #1707 , Embedding other sites with iframes #565 - Embedding made possible (requires a separate proposal);
API for change browser's header/address bar color #1667 - Controlled by the site now;
Can't scroll in safari #1403 - Scrolling is fixed;
How to use localStorage? #1399 , Accessing localStorage from zite #1054 , Allow sites to use localresources, IndexedDB, WebSql, etc #29 - localStorage, IndexedDB, etc. made possible (requires a separate proposal);
I make a WebGl game based on Unity3d. Then I put these files under my websites folder (clear all original files). When I open my web through ZeroNet, it just show nothing. #1237 - Fullscreen API without ZeroFrame;
Error: Permission denied to access property "document" #1236 , Allow zite loading outside iframe (for zite owners) #1262 - SecurityError's fixed;
Sandbox prevents creating web worker #1010 - Web Workers by path should work now;
Uncaught SecurityError: #469 - History API without ZeroFrame.
Implementation status
ETA: at most 1 week if no major issues are found
Abstract
Currently ZeroNet uses a wrapper for sidebar and notifications UI, and embeds site content with an iframe. This proposal fixes some issues caused by iframing by embedding ZeroNet UI into site content.
Rationale
Overview
Current architecture:
Safety layers are separated with double border.
No software has zero bugs. This includes security issues. There are many possible attack points here:
Proposed architecture;
Sure, it might look more difficult at the first glance, but security comes with a cost.
Resulting HTML
The resulting HTML (the one that browser receives) consists of a prefix and the real site
.htmlfile.Prefix
Prefix is a "magic" HTML code that sets up an analogue of what was a wrapper by creating a shadow DOM node. This ensures that the sidebar and notifications are shown correctly, independent of main site styles, and that it doesn't affect the site itself.
Gate
A gate is an iframe that acts like a gate between UiWebsocket and its user. The gate handler uses the referrer to check what permissions the websocket must have.
Fixed issues / added features
Implementation status
ETA: at most 1 week if no major issues are found