You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
# if SecurityCheck.validate(user_input, password) || raise(SecurityCheck) do :you_let_a_baddie_in end
220
221
```
221
222
223
+
## Sensitive Data Exposure
224
+
225
+
### Description
226
+
227
+
Sensitive data is any information that should be out of reach from all outsiders unless they have permission to access it, which in most cases would be considered "confidential data". Some examples of sensitive data are PHI (Protected Health Information) or PII (Personally Identifiable Information).
228
+
229
+
While it's obvious that we don't want data of this nature to get exposed, let's walk through some of the common instances in which it _can_ occur while using Elixir and how to prevent it from happening!
230
+
231
+
### Prevention
232
+
233
+
## Wrapping
234
+
235
+
Exceptions may result in console or log output that includes a stack trace. Mostly a stack trace shows the module/function/arity and the filename/line where the exception occurred, but for the function at the top of the stack the actual list of arguments may be included instead of the function arity.
236
+
237
+
To prevent sensitive data from leaking in a stack trace, the value may be wrapped in a closure: a zero-arity anonymous function. The inner value can be easily unwrapped where it is needed by invoking the function. If an error occurs and function arguments are written to the console or a log, it is shown as `#Fun<...>` or `#Function<...>`.
238
+
239
+
Secrets wrapped in a closure are also safe from introspection using [Observer](https://elixir-lang.org/getting-started/debugging.html#observer) and from being written to crash dumps.
240
+
241
+
### <spanstyle="color:blue;">Example</span>
242
+
243
+
```elixir
244
+
wrapped_secret =fn->System.get_env("SECRET") end
245
+
```
246
+
247
+
## Stacktrace Pruning
248
+
249
+
Another approach, useful in functions that call the standard library (e.g. crypto) or other functions that do not support wrapping secrets in a closure, is stripping argument values from the stack trace when an exception occurs. This can be done by wrapping the function call(s) in a try … catch expression (Erlang) or adding a rescue clause to a function body (Elixir), and stripping the function arguments before re-raising the exception
250
+
251
+
### <spanstyle="color:blue;">Example</span>
252
+
253
+
```elixir
254
+
defencrypt_with_secret(message, wrapped_secret) do
255
+
ComeCryptoLib.encrypt(message, wrapped_secret.())
256
+
rescue
257
+
e ->reraise e, prune_stacktrace(System.stacktrace())
[ETS tables](https://elixir-lang.org/getting-started/mix-otp/ets.html) are commonly used as a go to caching mechanism in-app. But did you know that they can be declared as private (through the use of the `:private` option when instantiating them)?
269
+
270
+
This prevents the table from being read by other processes, such as remote shell sessions. Private tables are also not visible in Observer.
271
+
272
+
### <spanstyle="color:red;">Quiz</span>
273
+
274
+
**We have decided that we do not want this ETS table to be read from other processes, so try making it private:**
275
+
276
+
```elixir
277
+
secret_table =:ets.new(:secret_table, [:public]) # ONLY EDIT THIS LINE
0 commit comments