Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Masking http(s)_proxy password from startup output. #17116

Merged
merged 5 commits into from
Sep 20, 2023
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions pkg/minikube/node/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,9 @@ import (
"os"
"os/exec"
"path/filepath"
"regexp"
"strconv"
"strings"
"sync"

"github.com/spf13/viper"
Expand All @@ -39,11 +41,26 @@ import (
"k8s.io/minikube/pkg/util/lock"
)

func maskProxyPassword(v string) string {
parts := strings.Split(v, "=")
if len(parts) == 2 {
key := strings.ToUpper(parts[0])
if key == "HTTP_PROXY" || key == "HTTPS_PROXY" {
pattern := `//([^:]+):[^\@]+@`
regexpPattern := regexp.MustCompile(pattern)
value := regexpPattern.ReplaceAllString(parts[1], "//$1:*****@")
v = key + "=" + value
}
}
return v
}

func showVersionInfo(k8sVersion string, cr cruntime.Manager) {
version, _ := cr.Version()
register.Reg.SetStep(register.PreparingKubernetes)
out.Step(cr.Style(), "Preparing Kubernetes {{.k8sVersion}} on {{.runtime}} {{.runtimeVersion}} ...", out.V{"k8sVersion": k8sVersion, "runtime": cr.Name(), "runtimeVersion": version})
for _, v := range config.DockerOpt {
v = maskProxyPassword(v)
out.Infof("opt {{.docker_option}}", out.V{"docker_option": v})
}
for _, v := range config.DockerEnv {
Expand Down
60 changes: 60 additions & 0 deletions pkg/minikube/node/config_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
/*
Copyright 2016 The Kubernetes Authors All rights reserved.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package node

import (
"testing"
)

func Test_maskProxyPassword(t *testing.T) {
type dockerOptTest struct {
input string
output string
}
var tests = []dockerOptTest{
{
input: "cats",
output: "cats",
},
{
input: "myDockerOption=value",
output: "myDockerOption=value",
},
{
input: "http_proxy=http://myproxy.company.com",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lets use minikube domain name here, so we dont get spam

minikube.sigs.k8s.io

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done!

output: "HTTP_PROXY=http://myproxy.company.com",
},
{
input: "https_proxy=http://[email protected]:8080",
output: "HTTPS_PROXY=http://[email protected]:8080",
},
{
input: "https_proxy=https://mary:am$uT8zB([email protected]:8080",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lets make this word obvious it is a fake password
such as
mary@iam$Fake!password

also lets make more example of password with other types of characters such as ' %&* (things that could break our regex)

Copy link
Contributor Author

@rmsilva1973 rmsilva1973 Sep 6, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Improved the regex robustness and the tests. I can't remember torturing regexes that much since I used to parse sendmail logs on SunOS 4.. 😊
Anyway, this is my first PR and I'm thankful for the feedback. I hope it's better now.

output: "HTTPS_PROXY=https://mary:*****@myproxy.company.com:8080",
},
{
input: "http_proxy=http://jdoe:mPu3z9uT#[email protected]:8080",
output: "HTTP_PROXY=http://jdoe:*****@myproxy.company.com:8080",
},
}
for _, test := range tests {
got := maskProxyPassword(test.input)
if got != test.output {
t.Errorf("maskProxyPassword(\"%v\"): got %v, expected %v", test.input, got, test.output)
}
}
}
8 changes: 7 additions & 1 deletion pkg/minikube/node/start.go
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -723,9 +723,15 @@ func validateNetwork(h *host.Host, r command.Runner, imageRepository string) (st
out.Styled(style.Internet, "Found network options:")
optSeen = true
}
k = strings.ToUpper(k) // let's get the key right away to mask password from output
// If http(s)_proxy contains password, let's not splatter on the screen
if k == "HTTP_PROXY" || k == "HTTPS_PROXY" {
pattern := `//(\w+):\w+@`
regexpPattern := regexp.MustCompile(pattern)
v = regexpPattern.ReplaceAllString(v, "//$1:*****@")
}
out.Infof("{{.key}}={{.value}}", out.V{"key": k, "value": v})
ipExcluded := proxy.IsIPExcluded(ip) // Skip warning if minikube ip is already in NO_PROXY
k = strings.ToUpper(k) // for http_proxy & https_proxy
if (k == "HTTP_PROXY" || k == "HTTPS_PROXY") && !ipExcluded && !warnedOnce {
out.WarningT("You appear to be using a proxy, but your NO_PROXY environment does not include the minikube IP ({{.ip_address}}).", out.V{"ip_address": ip})
out.Styled(style.Documentation, "Please see {{.documentation_url}} for more details", out.V{"documentation_url": "https://minikube.sigs.k8s.io/docs/handbook/vpn_and_proxy/"})
Expand Down