Subject: Re: bw/transport-protocol-policy

From: Brandon Williams <[email-masked]>
Date: Thu, 1 Dec 2016 11:35:24 -0800

On 12/01, Jeff King wrote:
> On Thu, Dec 01, 2016 at 10:14:15AM -0800, Brandon Williams wrote:
> 
> > >   1. The new policy config lets you say "only allow this protocol when
> > >      the user specifies it". But when http.c calls is_transport_allowed(),
> > >      the latter has no idea that we are asking it about potential
> > >      redirects (which obviously do _not_ come from the user), and would
> > >      erroneously allow them.
> > > 
> > >      I think this needs fixed before the topic is merged. It's not a
> > >      regression, as it only comes into play if you use the new policy
> > >      config. But it is a minor security hole in the new feature.
> > 
> > I agree and it should be an easy fix.  We can just add a parameter like
> > so:
> > 
> > diff --git a/transport.c b/transport.c
> > index 2c0ec76..d38d50f 100644
> > --- a/transport.c
> > +++ b/transport.c
> > @@ -723,7 +723,7 @@ static enum protocol_allow_config get_protocol_config(const char *type)
> >  	return PROTOCOL_ALLOW_USER_ONLY;
> >  }
> >  
> > -int is_transport_allowed(const char *type)
> > +int is_transport_allowed(const char *type, int redirect)
> >  {
> >  	const struct string_list *whitelist = protocol_whitelist();
> >  	if (whitelist)
> > @@ -735,7 +735,7 @@ int is_transport_allowed(const char *type)
> >  	case PROTOCOL_ALLOW_NEVER:
> >  		return 0;
> >  	case PROTOCOL_ALLOW_USER_ONLY:
> > -		return git_env_bool("GIT_PROTOCOL_FROM_USER", 1);
> > +		return git_env_bool("GIT_PROTOCOL_FROM_USER", !redirect);
> >  	}
> >  
> >  	die("BUG: invalid protocol_allow_config type");
> > 
> > That way the libcurl code can say it is asking if it is ok to redirect
> > to that protocol.
> 
> I wouldn't expect anyone to ever set GIT_PROTOCOL_FROM_USER=1, but it
> does behave in a funny way here, overriding the "redirect" flag. I think
> we'd want something more like:
> 
>   if (redirect < 0)
> 	redirect = git_env_bool("GIT_PROTOCOL_FROM_USER", 1);
> 
> and then pass in "-1" from transport_check_allowed().

I don't think I quite follow your solution but I came up with this:

  case PROTOCOL_ALLOW_USER_ONLY:
    return redirect ? 0 : git_env_bool("GIT_PROTOCOL_FROM_USER", 1);

Which should address the same issue.

-- 
Brandon Williams