Secret: Avoid leaking keys in logs

master
Didactic Drunk 2021-06-14 11:15:48 -07:00
parent 5293281ca9
commit 472ed1fc37
3 changed files with 19 additions and 1 deletions

View File

@ -9,7 +9,7 @@ Secrets hold sensitive information
The Secret interface manages limited time access to a secret and securely erases the secret when no longer needed.
Secret providers may implement additional protections via:
* `#noaccess`, `#readonly` or `readwrite`.
* `#noaccess`, `#readonly` or `#readwrite`
* Using [mprotect]() to control access
* Encrypting the data when not in use
* Deriving keys on demand from a HSM
@ -116,8 +116,13 @@ end
## What attacks does a Secret protect against?
* Timing attacks when comparing secrets by overriding `==`
* Leaking data in to logs by overriding `inspect`
* Wiping memory when the secret is no longer in use
TODO: describe implementations
## Other languages/libraries
* rust: [secrets](https://github.com/stouset/secrets/)

View File

@ -19,4 +19,12 @@ describe Crypto::Secret::Not do
end
end
end
it "doesn't leak key material" do
secret = Crypto::Secret::Not.new 5
secret.to_s.should match /\(\*\*\*SECRET\*\*\*\)$/
secret.inspect.should match /\(\*\*\*SECRET\*\*\*\)$/
secret.to_s.should_not match /Bytes|Slice/
secret.inspect.should_not match /Bytes|Slice/
end
end

View File

@ -100,6 +100,11 @@ module Crypto::Secret
end
end
# Hide internal state to prevent leaking in to logs
def inspect(io : IO) : Nil
io << self.class.to_s << "(***SECRET***)"
end
abstract def to_slice(& : Bytes -> Nil)
abstract def bytesize : Int32