diff --git a/providers/github.go b/providers/github.go index 9101c6cf..f6d78b2a 100644 --- a/providers/github.go +++ b/providers/github.go @@ -85,7 +85,8 @@ func (p *GitHubProvider) hasOrg(accessToken string) (bool, error) { return false, err } if resp.StatusCode != 200 { - return false, fmt.Errorf("got %d from %q %s", resp.StatusCode, endpoint, body) + return false, fmt.Errorf( + "got %d from %q %s", resp.StatusCode, stripToken(endpoint.String()), body) } if err := json.Unmarshal(body, &orgs); err != nil { @@ -140,7 +141,8 @@ func (p *GitHubProvider) hasOrgAndTeam(accessToken string) (bool, error) { return false, err } if resp.StatusCode != 200 { - return false, fmt.Errorf("got %d from %q %s", resp.StatusCode, endpoint, body) + return false, fmt.Errorf( + "got %d from %q %s", resp.StatusCode, stripToken(endpoint.String()), body) } if err := json.Unmarshal(body, &teams); err != nil { @@ -217,9 +219,10 @@ func (p *GitHubProvider) GetEmailAddress(s *SessionState) (string, error) { } if resp.StatusCode != 200 { - return "", fmt.Errorf("got %d from %q %s", resp.StatusCode, endpoint, body) + return "", fmt.Errorf("got %d from %q %s", + resp.StatusCode, stripToken(endpoint.String()), body) } else { - log.Printf("got %d from %q %s", resp.StatusCode, endpoint, body) + log.Printf("got %d from %q %s", resp.StatusCode, stripToken(endpoint.String()), body) } if err := json.Unmarshal(body, &emails); err != nil { diff --git a/providers/internal_util.go b/providers/internal_util.go index 436744cb..6d853ab8 100644 --- a/providers/internal_util.go +++ b/providers/internal_util.go @@ -9,6 +9,42 @@ import ( "github.com/bitly/oauth2_proxy/api" ) +// stripToken is a helper function to obfuscate "access_token" +// query parameters +func stripToken(endpoint string) string { + return stripParam("access_token", endpoint) +} + +// stripParam generalizes the obfuscation of a particular +// query parameter - typically 'access_token' or 'client_secret' +// The parameter's second half is replaced by '...' and returned +// as part of the encoded query parameters. +// If the target parameter isn't found, the endpoint is returned +// unmodified. +func stripParam(param, endpoint string) string { + u, err := url.Parse(endpoint) + if err != nil { + log.Printf("error attempting to strip %s: %s", param, err) + return endpoint + } + + if u.RawQuery != "" { + values, err := url.ParseQuery(u.RawQuery) + if err != nil { + log.Printf("error attempting to strip %s: %s", param, err) + return u.String() + } + + if val := values.Get(param); val != "" { + values.Set(param, val[:(len(val)/2)]+"...") + u.RawQuery = values.Encode() + return u.String() + } + } + + return endpoint +} + // validateToken returns true if token is valid func validateToken(p Provider, access_token string, header http.Header) bool { if access_token == "" || p.Data().ValidateURL == nil { @@ -28,7 +64,7 @@ func validateToken(p Provider, access_token string, header http.Header) bool { body, _ := ioutil.ReadAll(resp.Body) resp.Body.Close() - log.Printf("%d GET %s %s", resp.StatusCode, endpoint, body) + log.Printf("%d GET %s %s", resp.StatusCode, stripToken(endpoint), body) if resp.StatusCode == 200 { return true diff --git a/providers/internal_util_test.go b/providers/internal_util_test.go index ad42bf10..ccb5ed41 100644 --- a/providers/internal_util_test.go +++ b/providers/internal_util_test.go @@ -119,3 +119,14 @@ func TestValidateSessionStateExpiredToken(t *testing.T) { vt_test.response_code = 401 assert.Equal(t, false, validateToken(vt_test.provider, "foobar", nil)) } + +func TestStripTokenNotPresent(t *testing.T) { + test := "http://local.test/api/test?a=1&b=2" + assert.Equal(t, test, stripToken(test)) +} + +func TestStripToken(t *testing.T) { + test := "http://local.test/api/test?access_token=deadbeef&b=1&c=2" + expected := "http://local.test/api/test?access_token=dead...&b=1&c=2" + assert.Equal(t, expected, stripToken(test)) +}