View Source SensitiveData (Sensitive Data v0.1.0)
This library aims to make data leak prevention straightforward and convenient, by making it easy to follow most of the Erlang Ecosystem Foundation's recommendations regarding protecting sensitive data.
For a quick overview, take a look at the Getting Started and Cheatsheet pages.
While wrapping sensitive data within a SensitiveData.Wrapper
instance will
conform to many recommendations in the linked article (such as wrapping sensitive data in
a closure, pruning stack traces, and deriving the
Inspect
protocol), it doesn't cover others which may be relevant to your
situation (such as using the :private option
for ETS tables containing sensitive data, flagging the current process as
sensitive using :erlang.process_flag(:sensitive, true)
in processes holding sensitive data, and so on).
Beware
This library is intended to prevent accidental leakage of sensitive data, it WILL NOT keep data safe from a malicious actor that has access to your system. For example, the wrapped sensitive data could be read via BEAM introspection functionality, such as
:erlang.fun_info(..., :env)
Summary
Functions
Executes the provided function, ensuring no data leaks in case of error.
Reads a line from stdin, without echoing the input back to the console.
Types
@type exec_opts() :: [ into: SensitiveData.Wrapper.spec(), exception_redactor: SensitiveData.Redaction.exception_redactor(), stacktrace_redactor: SensitiveData.Redaction.stacktrace_redactor() ]
Functions
@spec exec((-> result), exec_opts()) :: result when result: term() | SensitiveData.Wrapper.t() | no_return()
Executes the provided function, ensuring no data leaks in case of error.
Options
:into
- aSensitiveData.Wrapper.spec/0
value into which thefun
execution result should be wrapped.:exception_redactor
- theSensitiveData.Redaction.exception_redactor/0
to use when redacting anException.t/0
. Defaults toSensitiveData.Redactors.Exception.drop/1
, which is also the fallback if the custom redactor fails. See Custom Failure Redaction.:stacktrace_redactor
- theSensitiveData.Redaction.stacktrace_redactor/0
to use when redacting a stack trace. Defaults toSensitiveData.Redactors.Stacktrace.strip/1
, which is also the fallback if the custom redactor fails. See Custom Failure Redaction.
Examples
iex> Map.get("SOME_PASSWORD", :foobar)
** (BadMapError) expected a map, got: "SOME_PASSWORD"
iex> SensitiveData.exec(fn ->
...> Map.get("SOME_PASSWORD", :foobar)
...> end)
** (SensitiveData.RedactedException) an exception of type `BadMapError` was raised in a sensitive context
Passing the execution result to a SecretData
module implementing
the SensitiveData.Wrapper
behaviour:
SensitiveData.exec(fn ->
System.fetch_env!("DATABASE_PASSWORD")
end, into: SecretData)
#SecretData<...>
@spec gets_sensitive(prompt, [{:into, SensitiveData.Wrapper.spec()}]) :: user_input | SensitiveData.Wrapper.t() when prompt: String.t(), user_input: String.t()
Reads a line from stdin, without echoing the input back to the console.
Options
:into
- aSensitiveData.Wrapper.spec/0
value into which the input should be wrapped. By default, the input is not wrapped and is returned as-is, similarly toIO.gets/2
.
Examples
To display a prompt and await user input:
SensitiveData.gets_sensitive("Enter your database password: ")
To do the same but wrap the result within a SecretData
module implementing
the SensitiveData.Wrapper
behaviour:
SensitiveData.gets_sensitive("Enter your database password: ",
into: SecretData)