Skip to content
  • Jeff King's avatar
    http: always update the base URL for redirects · 6628eb41
    Jeff King authored and Junio C Hamano's avatar Junio C Hamano committed
    If a malicious server redirects the initial ref
    advertisement, it may be able to leak sha1s from other,
    unrelated servers that the client has access to. For
    example, imagine that Alice is a git user, she has access to
    a private repository on a server hosted by Bob, and Mallory
    runs a malicious server and wants to find out about Bob's
    private repository.
    
    Mallory asks Alice to clone an unrelated repository from her
    over HTTP. When Alice's client contacts Mallory's server for
    the initial ref advertisement, the server issues an HTTP
    redirect for Bob's server. Alice contacts Bob's server and
    gets the ref advertisement for the private repository. If
    there is anything to fetch, she then follows up by asking
    the server for one or more sha1 objects. But who is the
    server?
    
    If it is still Mallory's server, then Alice will leak the
    existence of those sha1s to her.
    
    Since commit c93c92f3 (http: update base URLs when we see
    redirects, 2013-09-28), the client usually rewrites the base
    URL such that all further requests will go to Bob's server.
    But this is done by textually matching the URL. If we were
    originally looking for "http://mallory/repo.git/info/refs",
    and we got pointed at "http://bob/other.git/info/refs", then
    we know that the right root is "http://bob/other.git".
    
    If the redirect appears to change more than just the root,
    we punt and continue to use the original server. E.g.,
    imagine the redirect adds a URL component that Bob's server
    will ignore, like "http://bob/other.git/info/refs?dummy=1".
    
    We can solve this by aborting in this case rather than
    silently continuing to use Mallory's server. In addition to
    protecting from sha1 leakage, it's arguably safer and more
    sane to refuse a confusing redirect like that in general.
    For example, part of the motivation in c93c92f3
    
     is
    avoiding accidentally sending credentials over clear http,
    just to get a response that says "try again over https". So
    even in a non-malicious case, we'd prefer to err on the side
    of caution.
    
    The downside is that it's possible this will break a
    legitimate but complicated server-side redirection scheme.
    The setup given in the newly added test does work, but it's
    convoluted enough that we don't need to care about it. A
    more plausible case would be a server which redirects a
    request for "info/refs?service=git-upload-pack" to just
    "info/refs" (because it does not do smart HTTP, and for some
    reason really dislikes query parameters).  Right now we
    would transparently downgrade to dumb-http, but with this
    patch, we'd complain (and the user would have to set
    GIT_SMART_HTTP=0 to fetch).
    
    Reported-by: Jann Horn (work account)'s avatarJann Horn <jannh@google.com>
    Signed-off-by: default avatarJeff King <peff@peff.net>
    Signed-off-by: default avatarJunio C Hamano <gitster@pobox.com>
    6628eb41