diff --git a/README.md b/README.md index a349224..174a52a 100644 --- a/README.md +++ b/README.md @@ -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/) diff --git a/spec/not_spec.cr b/spec/not_spec.cr index 37e79b5..92faeed 100644 --- a/spec/not_spec.cr +++ b/spec/not_spec.cr @@ -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 diff --git a/src/crypto-secret/secret.cr b/src/crypto-secret/secret.cr index 4d0d2af..00e4f61 100644 --- a/src/crypto-secret/secret.cr +++ b/src/crypto-secret/secret.cr @@ -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