Skip to content

View-only desktop: suppress RFB input frames for a credential without desktop:input #15146

Open

Description

@mrveiss

Follow-up to #14964 (part of #14958).

Problem

The issue asked for view-only desktop access as a distinct capability from desktop input.
#14964 defines both (DeviceCapability.DESKTOP_VIEW, DESKTOP_INPUT) but cannot separate
them at the only desktop enforcement point
, so api/ws_security.enforce_ws_desktop_auth
requires BOTH before opening /{vnc_type}/websockify.

The reason is in the transport, not the policy. That socket is a raw RFB relay:
api/vnc_proxy._forward_client_to_vnc forwards the client's frames to the VNC server verbatim,
and the client->server direction is where KeyEvent (message type 4), PointerEvent (5) and
ClientCutText (6) live — alongside FramebufferUpdateRequest (3), which a viewer must be
able to send. So opening the socket grants input as inseparably as it grants view, and granting
desktop:view alone would be a view-only grant that is not view-only.

Requiring both is the honest strict reading, but it means the view-only mode the audit asked for
does not exist yet.

Proposed approach

Filter the client->server direction at RFB message level: forward SetPixelFormat (0),
SetEncodings (2) and FramebufferUpdateRequest (3); drop KeyEvent, PointerEvent and
ClientCutText when the credential lacks desktop:input.

This needs a real framing parser, not a first-byte check — the stream is bytes, not messages,
and SetEncodings/ClientCutText are variable length. A parser that resynchronises wrongly
either breaks the desktop or lets an input frame through, so it must fail closed: anything it
cannot frame confidently is dropped, not forwarded.

Constraints

  • A half-correct parser is worse than the current strict requirement — it would read as
    enforcement while passing input through.
  • Filtering sits in the hot path of every framebuffer update; it must not copy per frame.

Acceptance criteria

  • A credential holding desktop:view but not desktop:input can open the socket and
    receive framebuffer updates.
  • That credential's KeyEvent/PointerEvent/ClientCutText frames never reach the VNC
    server, asserted against the upstream socket, not against a helper.
  • A malformed or unframeable client message is dropped, never forwarded.
  • enforce_ws_desktop_auth then requires only desktop:view, with desktop:input
    enforced at the forwarder.

Activity

  1. github-actions commented on Aug 26, 2026

    @github-actions
    Contributor

    👋 Auto-triage could not confidently classify this issue (no confident signal). Could a maintainer add the appropriate labels (frontend, backend, infrastructure, docs, testing and good-first-issue, intermediate, advanced)?

  2. added
    area: ci-gatesWave 0 · cluster P — CI gates & merge integrity
    on Sep 1, 2026
  3. added this to the Backlog milestone on Sep 12, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    area: ci-gatesWave 0 · cluster P — CI gates & merge integrityci

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions