GoでパスワードなどをPrintfで出力させたくない

2016-07-12  /  Go

RailsのLoggerだとリクエストパラメータにパスワードなどが含まれていると、FILTEREDといった感じで生の情報が出力されない。

Goでも、例えば、以下のような構造体Userを fmt.Printf("%#v", u) で出力したときに Password が隠れて欲しい。

type User struct {
	Name     string
	Password string
}

ノーガード

特に何もしないと、そのまま出力される。

type User struct {
	Name     string
	Password string
}

func main() {
	u := &User{
		Name:     "namae",
		Password: "pass",
	}

	fmt.Printf("%+v", u)
	// &{Name:namae Password:pass}
}

[https://play.golang.org/p/HZuuaXwS4O]

そりゃそうだ。

Password を Stringer にしてみる

fmtで出力されるとき、StringerだとStringが呼ばれるはず。

type Password string

func (p Password) String() string {
	return "FILTERED"
}

type User struct {
	Name     string
	Password Password
}

func main() {
	u := &User{
		Name:     "namae",
		Password: Password("pass"),
	}

	fmt.Printf("%+v", u)
	// &{Name:namae Password:FILTERED}
}

[https://play.golang.org/p/hmNsB0yrbk]

お、できた!?

“%#v” には勝てない

%+v だと出力されないんだけど、%#vだと出力されてしまう…

type Password string

func (p Password) String() string {
	return "FILTERED"
}

type User struct {
	Name     string
	Password Password
}

func main() {
	u := &User{
		Name:     "namae",
		Password: Password("pass"),
	}

	fmt.Printf("%#v", u)
	// &main.User{Name:"namae", Password:"pass"}

}

[https://play.golang.org/p/1BT9E4dM17]

ポインタ型にしてみる

ポインタ型にしたらどうだろう。

type Password string

func (p Password) String() string {
	return "FILTERED"
}

type User struct {
	Name     string
	Password *Password
}

func main() {
	p := Password("pass")
	u := &User{
		Name:     "namae",
		Password: &p,
	}

	fmt.Printf("%#v", u)
	// &main.User{Name:"namae", Password:(*main.Password)(0x1040a120)}

}

[https://play.golang.org/p/_pcSzrx64p]

アドレスが出力されるので、とりあえずパスワードはわからない状態になった。

まとめ

で良いんだろうか?

もっと良い方法ないだろうか。

Published: 2016-07-12  /  Tags: Go  /  Share: X