WebDAV with CORS

Hi! Just a heads up about CORS. I'd like to be able to use WebDAV interface from a Progressive Web Application (PWA) but that will require explicitly allowing access via CORS headers on the server side. Additionally, it will also require explicitly allowing the WebDAV headers when CORS is active.
Just recently added this to rclone, so hopefully this helps: webdav: WebDAV-specific methods and headers by alensiljak · Pull Request #7495 · rclone/rclone · GitHub

Thanks for starting a discussion about this. Others may wish to comment further on how and where this fits in to zrok.

It sounds like a powerful enhancement to me, I didn't find any existing GitHub issues mentioning "cors," and I'm guessing the changes would be in http.go with logic like "if share type is drive, then add CORS headers." I'd have to research an appropriate CORS policy for the server to recommend to the browser. It should probably limit cross-origin to that particular zrok share's public subdomain, right? Would the WebDAV server also need to specify the web app's HTTP origin or only its own HTTP origin?

I recommend that you go ahead and raise the request in a GitHub issue, based on the details that emerge here (unless someone chimes in soon to say it's already in progress under another project card or there's some reason we can't do what you suggested). That way, the issue can be organized into the project board and you'll be subscribed to updates too.

Thanks! I've opened the issue at Allow access from a PWA (CORS headers) · Issue #522 · openziti/zrok · GitHub.

Based on Access-Control-Allow-Origin - HTTP | MDN , if not using "*", the server would have to specify the client app's URL. I.e. I'm calling from https://cashier-ii.alensiljak.eu.org, so it should be explicitly specified. That's rather difficult to know in advance, so the user should be able specify the allowed origin(s). I did not research this setting into depth since I was always accessing on a local network or via a tunnel. Hence I'm currently using * for testing.

I see PWAs as universal apps, so allowing access from them would be good to have.

My cursory analysis leads me to think a zrok drive share responding with Access-Control-Allow-Origin: * or Access-Control-Allow-Origin: {echo the requested origin} would fail to prevent cross-site scripting attacks because the HTTP server would always allow the requested origin.

I noticed that there's no possibility for the zrok user to provide their own CORS implementation with zrok drive because they only supply the directory target for drive mode, not an HTTP server. The HTTP server is handled by zrok drive.

So, for this to work, zrok drive, specifically the zrok "frontend" would have to be configured to respond with Access-Control-Allow-Origin: {preconfigured domain name of the client web app}, i.e. the PWA.

It would also be necessary for zrok frontend to handle a preliminary OPTIONS request from the legitimate browser client that probes for server capabilities.

Assuming the Access-Control-Allow-Methods and Access-Control-Allow-Headers values are predictable for all zrok drives, those wouldn't necessarily need to be configurable. Only the allowed origins must be configurable.

I'm imagining a user experience like this.

$ zrok reserve public --backend-mode drive --unique-name mywebdavshare --allowed-origin https://cashier-ii.alensiljak.eu.org:443 ./path/to/dir
[   0.440]    INFO main.(*reserveCommand).run: your reserved share token is 'mywebdavshare'
[   0.441]    INFO main.(*reserveCommand).run: reserved frontend endpoint: https://mywebdavshare.share.zrok.io

I used "reserve" as an example because it would be necessary to re-create the drive if the allowed origin changes, so reserving a unique name means that the domain name of the drive is stable from one configuration to the next.

The allowed origin(s) would be wired into the zrok configuration stored on the share's service in OpenZiti.

This seems like something we can work out for an upcoming release. I've backlogged the issue to be included in upcoming work.

1 Like

In regards to supporting multiple apps, my understanding is that only one origin is specified per header. But multiple headers are supported, then?
On the other hand, using * with authentication would be acceptable. Considering Ziti provides a tunnel, I would mostly recommend using this in private mode.

A private frontend (zrok access private) would be radically simpler to implement than a public frontend... The CORS headers could just be command-line flags to zrok access private.