Skip to content

Commit 8a2761a

Browse files
fix: remove OAuth token logging and redact sensitive data from CLI output
Remove unconditional log.Printf calls that leaked access tokens and refresh tokens to stderr after SSO login. Redact the callback URL (which contained the OAuth authorization code) and the authorization URL (which contained state nonce and code challenge). Additionally, add redaction of Authorization headers and OAuth token parameters in verbose HTTP dump output to prevent credential exposure when --verbose flag is used. Closes #449
1 parent 5446909 commit 8a2761a

2 files changed

Lines changed: 22 additions & 7 deletions

File tree

cmd/login.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -219,7 +219,7 @@ func oauth2login(
219219
// Authorization redirect callback from OAuth2 auth flow.
220220
// Handles both implicit and authorization code flow
221221
callbackHandler := func(w http.ResponseWriter, r *http.Request) {
222-
log.Printf("Callback: %s\n", r.URL)
222+
log.Printf("Callback received on: %s\n", r.URL.Path)
223223

224224
if formErr := r.FormValue("error"); formErr != "" {
225225
handleErr(w, fmt.Sprintf("%s: %s", formErr, r.FormValue("error_description")))
@@ -276,7 +276,8 @@ func oauth2login(
276276
opts = append(opts, oauth2.SetAuthURLParam("code_challenge_method", "S256"))
277277
url = oauth2conf.AuthCodeURL(stateNonce, opts...)
278278

279-
fmt.Printf("Performing %s flow login: %s\n", "authorization_code", url)
279+
authBaseURL := strings.SplitN(url, "?", 2)[0]
280+
fmt.Printf("Performing %s flow login: %s\n", "authorization_code", authBaseURL)
280281
time.Sleep(1 * time.Second)
281282
ssoAuthFlow(url, ssoLaunchBrowser)
282283
go func() {
@@ -293,8 +294,7 @@ func oauth2login(
293294
ctx, cancel := context.WithTimeout(ctx, 1*time.Second)
294295
defer cancel()
295296
_ = srv.Shutdown(ctx)
296-
log.Printf("Token: %s\n", tokenString)
297-
log.Printf("Refresh Token: %s\n", refreshToken)
297+
298298
return tokenString, refreshToken
299299
}
300300

pkg/config/config.go

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,8 @@ import (
2323
"net/http/httputil"
2424
"os"
2525
"path/filepath"
26-
strings "strings"
26+
"regexp"
27+
"strings"
2728
)
2829

2930
var (
@@ -37,6 +38,13 @@ var (
3738
ConfigPath = filepath.Join(os.Getenv("HOME"), ".microcks-cli", "config.yaml")
3839
)
3940

41+
var sensitiveHeaderPattern = regexp.MustCompile(
42+
`(?im)^(Authorization:\s*)(Bearer\s+)?(.+)$`,
43+
)
44+
var sensitiveParamPattern = regexp.MustCompile(
45+
`(?i)(access_token|refresh_token|id_token|code)=([^&\s]+)`,
46+
)
47+
4048
// CreateTLSConfig wraps the creation of tls.Config object for use with HTTP Client for example.
4149
func CreateTLSConfig() *tls.Config {
4250
tlsConfig := &tls.Config{}
@@ -76,7 +84,7 @@ func DumpRequestIfRequired(name string, req *http.Request, body bool) {
7684
if err != nil {
7785
fmt.Println("Got error while dumping request out")
7886
}
79-
fmt.Printf("%s", dump)
87+
fmt.Printf("%s", redactSensitiveContent(string(dump)))
8088
}
8189
}
8290

@@ -88,9 +96,16 @@ func DumpResponseIfRequired(name string, resp *http.Response, body bool) {
8896
if err != nil {
8997
fmt.Println("Got error while dumping response")
9098
}
91-
fmt.Printf("%s", dump)
99+
fmt.Printf("%s", redactSensitiveContent(string(dump)))
92100
if body {
93101
fmt.Println("")
94102
}
95103
}
96104
}
105+
106+
// redactSensitiveContent masks OAuth tokens and credentials in HTTP dump output.
107+
func redactSensitiveContent(dump string) string {
108+
redacted := sensitiveHeaderPattern.ReplaceAllString(dump, "${1}[REDACTED]")
109+
redacted = sensitiveParamPattern.ReplaceAllString(redacted, "${1}=[REDACTED]")
110+
return redacted
111+
}

0 commit comments

Comments
 (0)