Skip to content

Commit 9563f38

Browse files
committed
fix(core): RequestToCurl will strip any auth headers from logs.
1 parent e49957b commit 9563f38

File tree

2 files changed

+116
-6
lines changed

2 files changed

+116
-6
lines changed

auth_providers/auth_core.go

Lines changed: 43 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -800,19 +800,56 @@ func RequestToCurl(req *http.Request) (string, error) {
800800
// Add headers
801801
for name, values := range req.Header {
802802
for _, value := range values {
803+
// check if is Authorization header and skip it
804+
if strings.EqualFold(name, "Authorization") {
805+
// check if basic auth and skip it
806+
if strings.HasPrefix(value, "Basic ") {
807+
// Remove credentials and put in env variables as placeholder
808+
log.Printf(
809+
"[DEBUG] Found Basic auth in Authorization header, " +
810+
"replacing with env variable references",
811+
)
812+
curlCommand.WriteString(
813+
fmt.Sprintf(
814+
"-H %q ", fmt.Sprintf(
815+
"%s: Basic $(echo -n $\"%s,$%s\" | base64)", name,
816+
EnvKeyfactorUsername, EnvKeyfactorPassword,
817+
),
818+
),
819+
)
820+
continue
821+
} else if strings.HasPrefix(value, "Bearer ") {
822+
// Remove credentials and put in env variables as placeholder
823+
log.Printf("[DEBUG] Found Bearer token in Authorization header, replacing with kfutil command to fetch token")
824+
curlCommand.WriteString(
825+
fmt.Sprintf(
826+
"-H %q ", fmt.Sprintf(
827+
"%s: Bearer $(kfutil auth fetch-oauth-token)", name,
828+
),
829+
),
830+
)
831+
continue
832+
} else {
833+
// Skip other Authorization headers
834+
log.Printf("[ERROR] Skipping unhandled Authorization header: %s", name)
835+
continue
836+
}
837+
}
803838
curlCommand.WriteString(fmt.Sprintf("-H %q ", fmt.Sprintf("%s: %s", name, value)))
804839
}
805840
}
806841

807842
// Add the body if it exists
808843
if req.Method == http.MethodPost || req.Method == http.MethodPut {
809-
body, err := io.ReadAll(req.Body)
810-
if err != nil {
811-
return "", err
812-
}
813-
req.Body = io.NopCloser(bytes.NewBuffer(body)) // Restore the request body
844+
if req.Body != nil {
845+
body, err := io.ReadAll(req.Body)
846+
if err != nil {
847+
return "", err
848+
}
849+
req.Body = io.NopCloser(bytes.NewBuffer(body)) // Restore the request body
814850

815-
curlCommand.WriteString(fmt.Sprintf("--data %q ", string(body)))
851+
curlCommand.WriteString(fmt.Sprintf("--data %q ", string(body)))
852+
}
816853
}
817854

818855
return curlCommand.String(), nil

auth_providers/auth_core_test.go

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ package auth_providers_test
1616

1717
import (
1818
"net/http"
19+
"strings"
1920
"testing"
2021

2122
"github.com/Keyfactor/keyfactor-auth-client-go/auth_providers"
@@ -102,3 +103,75 @@ MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA7Q2+1+2+1+2+1+2+1+2+
102103
t.Fatalf("expected non-zero blocks")
103104
}
104105
}
106+
107+
func TestRequestToCurl(t *testing.T) {
108+
tests := []struct {
109+
name string
110+
method string
111+
url string
112+
headers map[string]string
113+
wantInCurl []string
114+
notWantInCurl []string
115+
}{
116+
{
117+
name: "Basic Auth",
118+
method: "GET",
119+
url: "https://example.com/api",
120+
headers: map[string]string{
121+
"Authorization": "Basic dXNlcjpwYXNz",
122+
},
123+
wantInCurl: []string{
124+
"curl", "-X", "GET", "https://example.com/api",
125+
"-H", "Authorization: Basic",
126+
},
127+
notWantInCurl: []string{
128+
"Authorization: Basic dXNlcjpwYXNz",
129+
},
130+
},
131+
{
132+
name: "Bearer Auth",
133+
method: "POST",
134+
url: "https://example.com/token",
135+
headers: map[string]string{
136+
"Authorization": "Bearer testtoken",
137+
"Content-Type": "application/json",
138+
},
139+
wantInCurl: []string{
140+
"curl", "-X", "POST", "https://example.com/token",
141+
"-H", "Authorization: Bearer",
142+
"-H", "Content-Type: application/json",
143+
},
144+
notWantInCurl: []string{
145+
"Authorization: Bearer testtoken",
146+
},
147+
},
148+
}
149+
150+
for _, tt := range tests {
151+
req, err := http.NewRequest(tt.method, tt.url, nil)
152+
if err != nil {
153+
t.Fatalf("failed to create request: %v", err)
154+
}
155+
for k, v := range tt.headers {
156+
req.Header.Set(k, v)
157+
}
158+
159+
curlStr, err := auth_providers.RequestToCurl(req)
160+
if err != nil {
161+
t.Errorf("%s: RequestToCurl returned error: %v", tt.name, err)
162+
continue
163+
}
164+
for _, want := range tt.wantInCurl {
165+
if !strings.Contains(curlStr, want) {
166+
t.Errorf("%s: curl string missing %q\nGot: %s", tt.name, want, curlStr)
167+
}
168+
}
169+
170+
for _, notWant := range tt.notWantInCurl {
171+
if strings.Contains(curlStr, notWant) {
172+
t.Errorf("%s: curl string contains unwanted %q\nGot: %s", tt.name, notWant, curlStr)
173+
}
174+
}
175+
t.Logf("%s: curl command: %s", tt.name, curlStr)
176+
}
177+
}

0 commit comments

Comments
 (0)