[Noisebridge-discuss] pip install secureconfig (actual hacking!)

Naomi Most pnaomi at gmail.com
Wed Apr 23 08:48:01 UTC 2014

Thanks, that's useful feedback.  That would be cool, having a CL
switch for python to zero all strings on destruction.

> Unfortunately, the only way to get data into a "secure" string was to construct it from a non-secure string... whose destructor did *not* clear its memory on the way out.

Python tries to copy references to data instead of actual data
whenever possible.  So in the very tight circumstances that I
illustrate in examples, and based on about half a day of poking and
prodding at the inner guts of a working python process, I'm at least
90% certain there aren't more copies somewhere.  I'm trying to learn
more so I can get that last 10% sure.

Oh, and zeromem.c was generated by Cython... so, yeah boilerplate.
I'm not much of a C programmer these days, and besides, SecureString
wasn't "the mission" -- it was kind of an afterthought.  (Large reason
why I am soliciting comment.)

A bit of background on the WHY of secureconfig:

The Mission was to restrict the movements of attackers who had somehow
acquired user-level access to a given deployment server or perhaps a
cloud server repository.  We determined after 3rd-party pen-testing
and our own internal revue that The Greatest Danger Could Be Your Own
Stupidity (i read that on a fortune cookie once) -- meaning if we're
gonna get pwned it'll be from a phishing attack or a stolen laptop or

So the imperative is to get sensitive data to stop being stored in
plaintext in repositories and on filesystems... but developers gonna
develop, and DevOps want automatic deployment.  Devs want versioned
config files, and DevOps want a minimum of involvement from
developers.  Devs also have an aversion to encrypting anything

So this library is what came out of a certain corporate threat model.
(The part about giving sudo to someone you don't trust was kind of
tongue in cheek.  A bit of a jab at Noisebridge members vis-a-vis
servers like pony and stallion.)

User-specific (not system-wide) environment variables are generally
considered a reasonably secure location to keep encryption keys.  Your
other typically available option would be chmod 700 directories to
store keys in files.  Beyond that you get into far more involved
scenarios that are going to require more help (technologically) than a
python library alone can provide.

Anyway, yeah, anybody with sudo can still pretty much pwn you, and
there's no point in performing a memory dump attack when you can just
decrypt the variables directly from the config files using the key you
discover in a file or environment variable if you poke around long

Thanks for giving this library some attention.  I think my immediate
action step will be to downplay the SecureString aspect (possibly just
not mention it in documentation for a while), because -- after reading
your reply and giving it a lot more thought -- I shouldn't implicitly
promise a "secure string" when it depends heavily on how the program
is written... and, come to think of it, whether the program completes


On Tue, Apr 22, 2014 at 11:47 PM, Josh Juran <jjuran at gmail.com> wrote:
> On Apr 21, 2014, at 11:22 PM, Naomi Most <pnaomi at gmail.com> wrote:
>> I made a library called secureconfig for python and pushed its first
>> minor release version earlier today.
>> https://pypi.python.org/pypi/secureconfig
>> https://bitbucket.org/nthmost/python-secureconfig
>> secureconfig provides interfaces to (currently 3) data structures,
>> including the .ini style data people like to use the configparser
>> class with.  You can encrypt/decrypt using keys stored in environment
>> variables, files, or strings.
> Environment variables may be visible to all users on a system, even guest users.
>> There's also a nifty class called SecureString that automatically
>> zeroes its string data after garbage collection or if you explicitly
> I once encountered a C++ class of the same name.  Sure enough, the destructor overwrote the memory before deallocating it. Unfortunately, the only way to get data into a "secure" string was to construct it from a non-secure string... whose destructor did *not* clear its memory on the way out.
>> call the "burn" method.  So if you're really paranoid you can do this:
>> scfg = SecureConfigParser.from_env(NAME_OF_ENV)
>> scfg.read('/path/to/config.ini')
>> password = SecureString(scfg.get('credentials', 'password'))
>> cnxn = ConnectToSomething(password)
>> # overwrite string data with zeroes:
>> password.burn()
> In order to make this work you need to be operating at system level.  I see you've arranged to call C's memset(), but are you sure that python hasn't made other copies of the data?  I'd be more comfortable if this were something built into the language, e.g. a command-line switch or language pragma that zeroes *all* strings on destruction, so you only pay for it when you want it, but once it's in effect it just works so you can't screw it up easily.
>> You can easily recover plaintext data from a memory dump with root
>> access, so the burn function is handy if you don't completely trust
>> everyone you've ever given sudo to.
> Giving superuser privileges to someone you don't trust completely is a contradiction.  Root can read the file where the key was stored.  Root can modify your Python library or the python executable (in memory or on disk).  Root can install a keylogger.  To share root *is* to trust completely.  How good an idea you feel that might be is another matter.
> Anyway, there's a window of opportunity between when the password is loaded or entered and when it's destroyed.  A user who can read your process' memory at all will also have ways of widening the window, e.g. sending SIGSTOP or attaching via ptrace() (or modifying your script to log the password).
>> This is the first time I've ever made a library that makes claims
>> about "security", and I want to make sure it gets picked apart
>> appropriately.  So feel free to critique code and documentation here.
> I've never looked at Python extension code before (so weight my remarks appropriately), but I'm disturbed by the sheer amount of boilerplate code in secureconfig/zeromem.c.
> <https://bitbucket.org/nthmost/python-secureconfig/src/04469e8ff00d50afad6a22ec3b37b147178cb0fa/secureconfig/zeromem.c>
> I'm not a cryptographer or infosec expert, and I'm not qualified to make assurances regarding security, but I'm a skilled programmer and mostly know what I'm talking about.
> I hope that helps.
> Josh

Naomi Theora Most
naomi at nthmost.com

skype: nthmost


More information about the Noisebridge-discuss mailing list