I’ve been playing with creating a custom Password
string type which would be securely logged and printed in obfuscated form.
I came up with:
struct Password <: AbstractString
contents::String
end
Base.show(io::IO, p::Password) = print(io, "*******")
Base.print(p::Password) = print("******")
Base.iterate(p::Password) = iterate(p.contents)
Base.iterate(p::Password, i::Int) = iterate(p.contents, i)
Base.ncodeunits(p::Password) = ncodeunits(p.contents)
Base.isvalid(p::Password, i::Int) = isvalid(p.contents, i)
secret_pass = Password("12345")
@show secret_pass
@info secret_pass
print(secret_pass)
Works fine with the exception of @info
. Output here:
secret_pass = ******
[ Info: 12345
******
What should be overwritten in order to affect logging output?
string
, apparently:
julia> Base.string(p::Password) = "***"
julia> @info secret_pass
[ Info: ***
1 Like
Thank you.
Interesting, I would’ve expected logging to rely on the show
or print
family of functions. Also, it looks like println
does not use print
either as it needs to be explicitly overwritten, which is surprising.
Finally, I was under the impression that string concatenation uses string
but it looks I was wrong.
struct Password <: AbstractString
contents::String
end
Base.show(io::IO, p::Password) = print(io, "******")
Base.print(p::Password) = print("******")
Base.println(p::Password) = print("******\n")
Base.string(p::Password) = "******"
Base.iterate(p::Password) = iterate(p.contents)
Base.iterate(p::Password, i::Int) = iterate(p.contents, i)
Base.ncodeunits(p::Password) = ncodeunits(p.contents)
Base.isvalid(p::Password, i::Int) = isvalid(p.contents, i)
secret_pass = Password("12345")
@show secret_pass
@warn secret_pass
@info secret_pass
println(secret_pass)
dump(secret_pass)
println("SELECT * FROM USERS WHERE username = 'foo' AND password = " * secret_pass)
println("SELECT * FROM USERS WHERE username = 'foo' AND password = MD5($secret_pass)")
Output:
secret_pass = ******
┌ Warning: ******
└ @ Main ~/Dropbox/Projects/PasswordType.jl:20
[ Info: ******
******
Password
contents: String "12345"
SELECT * FROM USERS WHERE username = 'foo' AND password = 12345
SELECT * FROM USERS WHERE username = 'foo' AND password = MD5(12345)