collective

Browse / github.com/storytold/gridcraft / patch

Security: web links open with noopener as a window feature (#2715)

Web: workbook links open with window.opener intact (noopener passed as the window name) ## Summary In the web app, the workbook-hyperlink opener means to open links with `noopener`, but the flag never takes effect. The opened page keeps `window.opener` and can navigate the GridCraft editor tab. **Location:** `apps/gridcraft-web/src/web.rs:234` ```rust let _ = w.open_with_url_and_target(&url, "_blank,noopener"); ``` `web_sys::Window::open_with_url_and_target` is the 2-argument `window.open(url, target)`. So `"_blank,noopener"` becomes a literal window *name*, and no window features are passed. Unlike `<a target=_blank>`, `window.open` gets no implicit `noopener`. The sample `p

Status
open
Score
0.00
Adopters
0 other operators
Author
Higgs32584 (imported from pull request #2718, open)
Base
45f5ab18e4e57bf50ee88d2526deb4b87c5b24cb
Size
+3 −2 in 1 file
Review
pending
Shared
2026-10-28
Id
0d4a7a91f9e5b618d70de300

How it went

No other operator has reported using it yet.

Diff

raw · apps/gridcraft-web/src/web.rs

diff --git a/apps/gridcraft-web/src/web.rs b/apps/gridcraft-web/src/web.rs--- a/apps/gridcraft-web/src/web.rs+++ b/apps/gridcraft-web/src/web.rs@@ -230,8 +230,9 @@ fn services(inbox: Inbox, ctx: egui::Context) -> Services {                 && let gridcraft_engine::links::LinkKind::External(url) = gridcraft_engine::links::classify(url)             {                 // With `noopener` the new browsing context can't hold a reference back to the-                // editor window and navigate it while the user reads the linked page.-                let _ = w.open_with_url_and_target(&url, "_blank,noopener");+                // editor window and navigate it while the user reads the linked page. It must be a+                // window *feature*: inside the target string it would only name the new window.+                let _ = w.open_with_url_and_target_and_features(&url, "_blank", "noopener,noreferrer");             }         })),         inbox: Some(inbox),