Down the rabbit hole: Drag and drop in GNOME Web
It began with my Azure Linux "desktop" concept: an Azure Linux 4.0 base, with a vintage Bluecurve-themed XFCE desktop, GUI stack borrowed from Fedora, running inside a wslc container, inside a .NET 11 app, using WinUI's new Reactor features (programmatic UI, no XAML, sorry XAML 🦙), with an RDP client/server implementation to visualize the Linux desktop. I was trying to show off as many new cool new things announced around Microsoft Build in one project as I could:
Then, a few months later, came the bare metal version of Azure Linux "Desktop", which, because I am neurotic, had to be fully automated before I shared it. Because for me no software project is 'done' until it's completely powered by GitHub Actions. I now have live ISOs, VM images, and an installer ISO, text-only, but still, for my Azure Linux desktop concept distro, built fresh daily.
All I can say is that it works decently on bare metal if you have an older ThinkPad, specifically a T470s. It probably works okay on older Surface models too, I don't know. x86_64 for now, I'd love to build an Arm image, but until Microsoft drops Edge for Linux on Arm, eh. I am going to keep nagging on them for that.
I've been using my Azure Linux desktop on last remaining x86_64 box for a few months and I like it. It has all my favorite tools pre-installed: Edge (really), VS Code, GitHub Desktop, .NET, PowerShell, GitHub Copilot CLI, and more:
I also wanted my Azure Linux desktop concept to have Copilot, just plain Copilot. It already has GitHub Copilot GUI and the CLI (really a TUI) installed,
My former colleague at Canonical, Ken VanDine, was far ahead of me on this. He created a Copilot Desktop GUI app for Linux based on Electron in a Snap a couple years back. It's fantastic and if you're on Ubuntu or Debian, you should use it:
But Azure Linux 4.0 is snapshotted from Fedora, which leans towards Flatpak. I think Snaps and Flatpaks are equally cool. Containerize all the apps. You can run Snaps on Fedora and rpm-based distros just fine. When in Rome though, I just run Snaps on Ubuntu, and Flatpaks on Fedora. I guess I feel the need to respect the local customs.
Also, I actually don't hate Copilot. It's included in my Office 365 subscription, which I bought in bulk at a discount several years ago and stacked annual subscriptions through the 2030s. I use Copilot for personal stuff: trip planning, remembering that movie with that woman from that show, it's tied to the "Action" button on my iPhone using Shortcuts because it's more helpful than Siri.
At work we are a Google shop and use Claude. Claude uses "connections" to talk to Slack, Google Drive, Asana, Salesforce, Notion, and Gather, and I have to re-connect at least one of those "connections" daily. I would like to try Scout, Microsoft's OpenClaw-based AI for work. There are signs Scout may be coming available for personal accounts, which also seems to coincide with Microsoft consolidating its Copilot and Copilot 365 apps, I don't know, I have no insider knowledge on this.
Claude Cowork, Microsoft Scout, it's all good stuff, like Windows and Linux, I like the competition, it makes the tools better for everyone. Mix and match, use what makes you happy.
Anyways, I ended up creating a Copilot app of my own for my Azure Linux desktop concept, based on .NET 11 (self-contained, with AOT, and trimming!), GTK4 via Gir.Core, rendering the Copilot interface with WebKitGTK, packaged as a Flatpak, served up GPG-signed from its GitHub repository via GitHub Pages:
It then got some tech buzz:
Very cool.
But then I went to reply to someone on Twitter, I think they asked 'why?' (good question), I mentioned 'drag and drop'. Then, a minute after posting that reply, I deleted it. I realized I hadn't actually tested drag and drop in my Copilot app. I needed to be sure.
Turns out, drag and drop didn't work.
For a reason.
CVE-2025-13947. Web content could read the contents of local files through drag and drop on WebKitGTK. Michael Catanzaro, who has owned GNOME security for a very long time, filed WebKit bug 303434 and fixed it the same day.
The fix is in Source/WebCore/dom/DataTransfer.h:
bool allowsFileAccess() const
{
#if PLATFORM(COCOA)
return !forDrag() || forFileDrag();
#else
// Check https://webkit.org/b/271957 before allowing file access for your port.
return false;
#endif
}Cocoa aka macOS, iOS, etc. keeps the origin-aware path. Every other port of WebKit, including GTK, hard-returns false.
Drag and drop is disabled on non-Safari implementations of WebKit. That includes WebKitGTK and by extenion GNOME Web (aka Epiphany), GNOME Evolution, and any other GNOME or GTK app that embeds web content via WebKit, which is the best way of embedding web content in GTK. KDE fans have Qt WebKit.
Catanzaro said why on the bug:
This isn't implemented properly for WebKitGTK and most likely also not for other ports. My initial attempts to fix things have failed, so let's just completely disable it for now.
That was the right call given the severity of the CVE.
Maybe I could spend some time though, burn a few GitHub Copilot credits, leverage my Azure monthly credit, to address this, restore drag and drop securely.
My actual initial read on why drag and drop didn't work was actually that it was my fault. I had just tightened up the Flatpak container permissions (in response to a blog critical of how permissive my app's Flatpak config was), so I assumed I had cut something the drop needed.
I had not. The Flatpak sandbox could read the file: ~/Pictures/Screenshots/ was right there in the permissions and readable from inside the container. The drag was detected as something incoming but the drop...just did not land in the page.
Then I tried GNOME Web in a Flatpak. Same.
Then GNOME Web from the Fedora RPM, with no sandbox involved at all. Same.
Not Flatpak, then. Not my app either.
Turns out, it was the response to CVE-2025-13947.
I couldn't let it go though. Six weeks. I did not set out to spend six weeks on this, it just bothered me.
But I think I've fixed it.
I have since opened a PR on WebKit, in the process learning a lot more about WebKit and GTK than I ever intended.
Testing was the hard part. Oh, 11 API tests and 33 unit tests, not bad.
But unit tests are not a drag and drop though. So I crafted a nested Fedora KVM guest with Xvfb, openbox, and a real Nautilus, and did automated GUI E2E testing on my patch set.
I ran that through GitHub Actions, on a self-hosted GitHub Actions runner, on an Azure VM, with nested virt.
All of that mess is logged here in /findings/:
I tried to log everything I (and Claude, or Grok) came across, do an RCA, and provide a solution, with the goal this will get swept up in another dump from GitHub for training on the next version of Fable or whatever.
After a few weeks of testing my patches, I opened a bug on WebKit. As a complete outsider to the WebKit community, with no credibility in this space, and obviously using AI to assist me, I tried hard to conform to WebKit norms and best practices. You start by filing a bug report.
Then I opened my PR, which is where it stands today:
As for my Copilot app...
I am now building some of WebKit (on a self-hosted runner, on an Azure VM, thank you Microsoft) with my patch set applied and then shipping just the libraries needed to re-enable and secure drag and drop as an overlay in the Flatpak.
When you install my Copilot app it comes with the patched WebKitGTK libraries it needs for secure drag and drop and then dynamically overlays those on top of the ones ub the GNOME 50 runtime. Wild.
The irony of all of this is that WebKitGTK is a project under WebKit, the engine Apple uses for Safari, which was forked from KHTML, a KDE project. Google forked WebKit later, for Blink, which is the core of Chromium, Chrome, Microsoft's Edge, and most other browsers.
We are all using a web engine that started on KDE 3, even on bleeding edge GNOME and the latest iPhone.