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)