Skip to content

Proposal: Reverse iframe #2169

@purplesyringa

Description

@purplesyringa

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:

┌─────────────────────────────────────────────────────┐
│ 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

Implementation status

  • Prefix
  • Gate
  • 0 button
  • Sidebar
  • Debug logs
  • Notifications
  • Modified panel
  • Old wrapper compatiblity
  • Local storage
  • Wrapper commands
    • innerReady [compat]
    • innerLoaded & wrapperInnerLoaded [compat]
    • wrapperNotification, wrapperConfirm, wrapperPrompt, wrapperProgress
    • wrapperSetViewport [compat]
    • wrapperSetTitle [compat]
    • wrapperReload [compat]
    • wrapperGetLocalStorage & wrapperSetLocalStorage
    • wrapperPushState, wrapperReplaceState, wrapperGetState [compat]
    • wrapperGetAjaxKey
    • wrapperOpenWindow [compat]
    • wrapperPermissionAdd
    • wrapperRequestFullscreen [compat]
    • wrapperWebNotification & wrapperCloseWebNotification [compat]

ETA: at most 1 week if no major issues are found

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions