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

Naomi Most pnaomi at gmail.com
Wed Apr 23 09:03:55 UTC 2014


Just thought of another reason why SecureString is a silly idea:
memory utilization varies by python interpreter implementation.  :p

Sometimes I just get overexcited about some weird idea I have over a weekend.

--Naomi



On Wed, Apr 23, 2014 at 1:48 AM, Naomi Most <pnaomi at gmail.com> wrote:
> 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
> something.
>
> 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
> themselves.
>
> 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
> enough.
>
> 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
> successfully.
>
> --Naomi
>
>
>
> 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
> +1-415-728-7490
>
> skype: nthmost
>
> http://twitter.com/nthmost



-- 
Naomi Theora Most
naomi at nthmost.com
+1-415-728-7490

skype: nthmost

http://twitter.com/nthmost


More information about the Noisebridge-discuss mailing list