react-x11 2.51.0 → 2.52.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +87 -54
- package/docs/README.md +410 -0
- package/docs/accessibility.md +628 -0
- package/docs/appearance.md +416 -0
- package/docs/architecture/accessibility.md +470 -0
- package/docs/architecture/animation.md +707 -0
- package/docs/architecture/container-queries.md +525 -0
- package/docs/architecture/custom-layout.md +334 -0
- package/docs/architecture/drag-and-drop.md +941 -0
- package/docs/architecture/element-layer-contents.md +622 -0
- package/docs/architecture/frame-pacing.md +255 -0
- package/docs/architecture/grid-layout.md +358 -0
- package/docs/architecture/protocol-efficiency.md +357 -0
- package/docs/architecture/video.md +1149 -0
- package/docs/architecture/windowed-regions.md +854 -0
- package/docs/click-to-component.md +125 -0
- package/docs/clipboard.md +281 -0
- package/docs/components.md +1749 -0
- package/docs/dbus.md +277 -0
- package/docs/debugging.md +464 -0
- package/docs/desktop-calendar.md +284 -0
- package/docs/desktop.md +648 -0
- package/docs/devtools.md +250 -0
- package/docs/drag-and-drop.md +663 -0
- package/docs/ecosystem/animation.md +394 -0
- package/docs/ecosystem/data-fetching.md +201 -0
- package/docs/ecosystem/dev-tooling.md +436 -0
- package/docs/ecosystem/forms.md +313 -0
- package/docs/ecosystem/headless.md +219 -0
- package/docs/ecosystem/i18n.md +89 -0
- package/docs/ecosystem/icons.md +410 -0
- package/docs/ecosystem/layout.md +216 -0
- package/docs/ecosystem/routing.md +146 -0
- package/docs/ecosystem/state.md +361 -0
- package/docs/ecosystem/testing.md +500 -0
- package/docs/ecosystem/theming.md +540 -0
- package/docs/ecosystem.md +473 -0
- package/docs/elements.md +2762 -0
- package/docs/embedding.md +288 -0
- package/docs/events.md +1025 -0
- package/docs/extending.md +2242 -0
- package/docs/eyedropper.md +223 -0
- package/docs/filedialog.md +258 -0
- package/docs/frame.md +580 -0
- package/docs/gl.md +170 -0
- package/docs/globalmenu.md +278 -0
- package/docs/glx.md +137 -0
- package/docs/macos.md +3295 -0
- package/docs/notifications.md +164 -0
- package/docs/packaging.md +611 -0
- package/docs/permissions.md +148 -0
- package/docs/react-features.md +430 -0
- package/docs/remote.md +223 -0
- package/docs/scale.md +339 -0
- package/docs/security.md +132 -0
- package/docs/styling.md +1928 -0
- package/docs/system.md +599 -0
- package/docs/testing.md +514 -0
- package/docs/typescript.md +117 -0
- package/docs/uri-schemes.md +380 -0
- package/docs/wayland-backend.md +591 -0
- package/docs/wayland.md +545 -0
- package/docs/windows-embedding.md +271 -0
- package/docs/windows-gl.md +221 -0
- package/docs/windows-integrations.md +233 -0
- package/docs/windows.md +1404 -0
- package/package.json +10 -3
- package/src/bus.js +39 -26
- package/src/cli/create.d.ts +43 -0
- package/src/cli/create.js +305 -0
- package/src/cli/env.js +484 -0
- package/src/cli/index.js +29 -2
- package/src/cli/templates/AGENTS.template.md +195 -0
- package/src/cli/templates/DESIGN.template.md +269 -0
- package/src/desktopintegration.js +2 -1
- package/src/desktopsettings.js +193 -24
- package/src/filedialog.js +3 -3
- package/src/keyboardstate.js +28 -0
- package/src/node.d.ts +10 -10
- package/src/portal.js +31 -0
- package/src/screencolor.js +5 -10
- package/src/types/system.d.ts +8 -6
- package/src/wayland/app.js +59 -0
- package/src/wayland/clipboard.js +14 -7
- package/src/wayland/connection.js +3 -0
- package/src/wayland/context2d.js +129 -10
- package/src/wayland/protocols/index.json +6 -0
- package/src/wayland/protocols/xdg-foreign-unstable-v2.json +1 -0
- package/src/wayland/seat.js +28 -1
- package/src/wayland/swapchain.js +23 -0
- package/src/wayland/xkb.js +137 -0
package/docs/security.md
ADDED
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
# Security model
|
|
2
|
+
|
|
3
|
+
Read this before you decide what to put in a react-x11 window.
|
|
4
|
+
|
|
5
|
+
## X11 has no isolation between clients
|
|
6
|
+
|
|
7
|
+
Any program connected to an X display can read any other program's window
|
|
8
|
+
contents, grab the keyboard, and synthesize or record input. Not through a
|
|
9
|
+
bug — that is the 1987 design. X11 predates the idea that programs on one
|
|
10
|
+
machine might not trust each other, and the protocol's power was the point.
|
|
11
|
+
|
|
12
|
+
It is not theoretical, and it is not hard. node-x11 ships bindings for both
|
|
13
|
+
extensions that make it a five-line program on a shared display:
|
|
14
|
+
|
|
15
|
+
- **XTEST** (`x11/lib/ext/xtest.js`) — `FakeInput` synthesizes key presses
|
|
16
|
+
and pointer events indistinguishable from real ones.
|
|
17
|
+
- **RECORD** (`x11/lib/ext/record.js`) — a keylogger, by design; it exists
|
|
18
|
+
so that macro recorders can work.
|
|
19
|
+
|
|
20
|
+
Plus `GetImage` on another client's window, which needs no extension at all
|
|
21
|
+
and is what this project's own [framed screenshots](../AGENTS.md) use.
|
|
22
|
+
|
|
23
|
+
Two consequences, both practical:
|
|
24
|
+
|
|
25
|
+
1. **Do not run untrusted programs on a display you use.** A malicious npm
|
|
26
|
+
postinstall script that reaches `$DISPLAY` owns your session — your
|
|
27
|
+
browser's rendered pages, your password manager's window, your
|
|
28
|
+
keystrokes.
|
|
29
|
+
2. **Do not treat a react-x11 window as a confidential surface.** If a
|
|
30
|
+
secret must not be readable by other software on that display, it does
|
|
31
|
+
not belong in an X11 window. This applies to every X11 toolkit equally;
|
|
32
|
+
react-x11 has no way to change it and does not pretend to.
|
|
33
|
+
|
|
34
|
+
Under Wayland this is different — a Wayland client cannot read its
|
|
35
|
+
neighbours — but react-x11 running under Xwayland is inside the X11 sandbox
|
|
36
|
+
with every other X client, so it shares theirs and not the compositor's. The
|
|
37
|
+
opt-in Wayland backend (`backend: 'wayland'`,
|
|
38
|
+
[wayland-backend.md](wayland-backend.md)) is a native Wayland client instead,
|
|
39
|
+
and is isolated the way any other one is. The Cocoa and win32 backends
|
|
40
|
+
connect to no X display at all, so what isolation they have is the
|
|
41
|
+
platform's, not X11's.
|
|
42
|
+
|
|
43
|
+
## `$XAUTHORITY` is a password
|
|
44
|
+
|
|
45
|
+
Access to an X display is a **bearer token**: the MIT-MAGIC-COOKIE-1 cookie
|
|
46
|
+
in `~/.Xauthority` (or wherever `$XAUTHORITY` points). node-x11 sends it on
|
|
47
|
+
connect (`x11/lib/auth.js`). Whoever holds the cookie has the display, with
|
|
48
|
+
everything in the section above.
|
|
49
|
+
|
|
50
|
+
So:
|
|
51
|
+
|
|
52
|
+
- **Never bake it into a container image.** `COPY . /app` with an
|
|
53
|
+
`.Xauthority` in the build context ships your display credentials to
|
|
54
|
+
whoever pulls the image.
|
|
55
|
+
- **Never log it, and never put it in a bug report.** Nor
|
|
56
|
+
`xauth list` output, nor a strace of the connect handshake.
|
|
57
|
+
- **Do not mount `~/.Xauthority` into a container** you would not trust with
|
|
58
|
+
your desktop. Mounting `/tmp/.X11-unix` has the same effect.
|
|
59
|
+
- Cookies are per-display and long-lived. Rotating one means
|
|
60
|
+
`xauth remove` / `xauth generate`, not restarting the app.
|
|
61
|
+
|
|
62
|
+
`ssh -X` sidesteps all of this: it creates a **separate, per-session,
|
|
63
|
+
expiring** cookie on the remote side, which is worth far less if it leaks.
|
|
64
|
+
That is a security argument for `ssh -X` beyond the encryption.
|
|
65
|
+
|
|
66
|
+
## Prefer `ssh -X` over `ssh -Y`
|
|
67
|
+
|
|
68
|
+
`-X` runs the app as an untrusted client: it cannot read other windows,
|
|
69
|
+
cannot grab the keyboard, cannot record input. `-Y` turns those restrictions
|
|
70
|
+
off and hands the remote host your whole session.
|
|
71
|
+
|
|
72
|
+
**react-x11 should work under `-X`.** It draws into windows it created,
|
|
73
|
+
which is exactly what untrusted mode allows. **If it does not, that is a bug
|
|
74
|
+
worth filing** rather than a reason to switch to `-Y`. That is a deliberate
|
|
75
|
+
position: most toolkits' documentation says "use `-Y` if `-X` misbehaves",
|
|
76
|
+
which quietly trades the entire isolation model for a workaround.
|
|
77
|
+
|
|
78
|
+
The one thing untrusted mode costs you is a cookie that expires — see
|
|
79
|
+
[remote.md](remote.md#the-failure-that-looks-like-a-crash), because the
|
|
80
|
+
symptom looks like a crash rather than a permission problem.
|
|
81
|
+
|
|
82
|
+
## Never `xhost +`
|
|
83
|
+
|
|
84
|
+
`xhost +` disables access control for every host on the network. `xhost
|
|
85
|
+
+local:` does it for every user on the machine, including the ones you did
|
|
86
|
+
not have in mind. Both are common advice for "X11 in Docker" and both mean
|
|
87
|
+
"anything that can reach my display now owns my session".
|
|
88
|
+
|
|
89
|
+
The right tool is `xauth`: extract the cookie for one display and give it to
|
|
90
|
+
one consumer.
|
|
91
|
+
|
|
92
|
+
```sh
|
|
93
|
+
# hand a container the cookie for :0, and nothing else
|
|
94
|
+
xauth nextract - "$DISPLAY" | docker exec -i box xauth nmerge -
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
`ssh -X` is better still, because the cookie it hands over is not the one
|
|
98
|
+
that opens your desktop.
|
|
99
|
+
|
|
100
|
+
## What react-x11 does and does not do
|
|
101
|
+
|
|
102
|
+
**Does:**
|
|
103
|
+
|
|
104
|
+
- Sends the cookie ntk/node-x11 read from `$XAUTHORITY` — the standard
|
|
105
|
+
handshake, nothing custom.
|
|
106
|
+
- Contains a throwing event handler rather than letting it take the process
|
|
107
|
+
([events.md](events.md#when-a-handler-throws)); a bad handler is a bug, not
|
|
108
|
+
a way to wedge the app.
|
|
109
|
+
- Bounds what it draws to the damaged region, which is a performance
|
|
110
|
+
property but also means less of your window crosses the wire per frame.
|
|
111
|
+
|
|
112
|
+
**Does not:**
|
|
113
|
+
|
|
114
|
+
- Defend against a hostile X server. The server you connect to sees
|
|
115
|
+
everything you draw, everything you type into your own windows, and holds
|
|
116
|
+
your clipboard. Connecting to an X display is trusting it completely —
|
|
117
|
+
there is no protocol-level way to do otherwise, and no library can add
|
|
118
|
+
one. `DISPLAY=evil.example:0` is equivalent to handing over the session.
|
|
119
|
+
- Sanitize content. `<svg>` renders the markup you give it through ntk's
|
|
120
|
+
SvgView, and a document component renders the source you hand it —
|
|
121
|
+
untrusted markup should be treated the way you would treat it in a
|
|
122
|
+
browser. Anything that fetches a remote resource on a document's behalf
|
|
123
|
+
is yours to police.
|
|
124
|
+
- Isolate one window from another within an app. Every node in a root shares
|
|
125
|
+
one connection and one process; `trapFocus` is a focus policy, not a
|
|
126
|
+
security boundary, and neither is a modal `Dialog`
|
|
127
|
+
([components.md](components.md#dialog)).
|
|
128
|
+
- Encrypt anything. That is `ssh`'s job.
|
|
129
|
+
|
|
130
|
+
## Reporting a vulnerability
|
|
131
|
+
|
|
132
|
+
See [SECURITY.md](../SECURITY.md).
|