In my Haskell application I implemented the following mechanism for passing sensitive information to the binary (without resorting to CLI parameters):
TemplateHaskell
mechanism for reading environment variables at compile time:{-# LANGUAGE TemplateHaskell #-}
...
import Language.Haskell.TH.Env
...
myPrecious :: String
myPrecious = fromMaybe "" $$(envQ "MY_PRECIOUS")
...
MY_PRECIOUS=<secret> stack build
and it then gets bound to myPrecious
on the Haskell sideMY_PRECIOUS
compiled in, so it won't be visible from the operating system level (e.g. via ps aux
)Trouble is, I can now open that binary in a text editor or create a memory dump (e.g. with GDB) and with a little determination dig up the secret, especially if I know the context in which it is being used - I'm assuming that some malicious actor might have obtained access to the source code. So I've been wondering, is there any way to force GHC to produce a more obfuscated/garbled binary, in which such values would not be readily visible. I'm aware that no such protection scheme can be bulletproof, but I'm looking for a way to make the intruder's task harder.
Obfuscation is a total waste of time. You'll end up spending days trying to come up with something clever only for a rookie reverse engineer to defeat it in minutes. Instead, you should set up actual security rather than security through obscurity, with something like this:
Now opening the binary in a text editor will yield nothing, since the secrets aren't in it at all, and taking a memory dump is impossible since the kernel doesn't let you do that to a setgid process.