Skip to content

Add CORS headers to git clone and git push

Will Hilton requested to merge wmhilton/gitlab-workhorse:browser-cors into master

Problem Description

Git clone and and git push are historically thought of as a desktop or server operation. But they can done in the browser using client-side JavaScript libraries such as js-git, es-git, or isomorphic-git (Disclaimer: I'm the author of isomorphic-git.) This enables web-based IDEs that can clone and push directly with git. These libraries use XMLHttpRequest or window.fetch to communicate to the git "smart" http backend to negotiate packfile download and/or upload.

However there are same-origin limitations on certain requests made in the browser, and git clone and git push - by nature of their exotic Content-Types and that the response is transparently parsed by JavaScript - meet the criteria of those limitations. Meaning that my site, example.com, cannot make a git clone request directly to gitlab.com, unless gitlab.com enables it with an Access-Control-Allow-Origin header.

Forcing users to use proxies is a security concern

In cases where developers have tried to make "git clone & push in the browser" work, they have resorted to using proxies (e.g. @es-git/node-git-proxy and cors-buster) to inject CORS headers. This poses no security concern when cloning a public git repository. However, when pushing to a repo, Basic Auth headers have to be forwarded through the proxy server. This is less than ideal. With a more complex server-side setup, OAuth could be used instead. However this diminishes the advantage of having a client-side library to push and pull at all, by making it rely on a third-party service.

Proposal

This merge request adds the two lines of code that make it possible to clone and push directly from a website:

w.Header().Set("Access-Control-Allow-Origin", "*")
w.Header().Set("Access-Control-Allow-Headers", "Content-Type, Authorization")

Note: It doesn't make sense to set "Access-Control-Allow-Origin" to anything other than "*", any more than it would make sense to limit who can run "git clone" based on their desktop IP address.

Testing

I have tested this on my own local instance of Gitlab, using the gitlab-development-kit, and confirm that these modifications enable me to clone and push from my browser using isomorphic-git.

Links / references

Merge request reports