mongodb / winkerberos

A native Kerberos client implementation for Python on Windows
Apache License 2.0
54 stars 15 forks source link

Allow usage of bytearray objects (or other raw buffers) for secure password passing #6

Closed schlenk closed 8 years ago

schlenk commented 8 years ago

Python offers a memoryview or buffer interface to raw-bytes, e.g. to bytearrays, mmap or custom objects implementing the buffer interface. PyString/PyBytes objects are inherently dangerous for passing password data, as those cannot be zeroed reliably after use. But buffer objects can be zeroed, as they are mutable string like structures.

So using z# instead of the z modifier for PyArg_ParseTupleAndKeywords would naturally allow using those more secure ways to pass password data to winkerberos.

behackett commented 8 years ago

This may not work with #1. All string fields of SEC_WINNT_AUTH_IDENTITY have to be wide character (Py_UNICODE) or 8 bit. You set the Flags field appropriately. It doesn't appear that you can mix the types.

https://msdn.microsoft.com/en-us/library/windows/desktop/aa380131(v=vs.85).aspx

behackett commented 8 years ago

Actually, we can probably coerce any object that implements the buffer interface to a unicode object.

behackett commented 8 years ago

I'm not convinced of the usefulness of this feature. There is an interesting relevant discussion here:

http://bugs.python.org/issue17405

Any support for securely wiping password data is best effort only. One example in issue17405 is the OS swapping your password data to disk. pyca/cryptography seems to have given up on the idea of secure memory wiping, opting to document limitations instead:

https://github.com/pyca/cryptography/pull/845

That said, I've developed a patch to do what you want. It was interesting to learn how the buffer interface works, if nothing else. I'll push it to a branch if you want to test it out.

schlenk commented 8 years ago

Thanks.

Security is always kind of best effort. pyca/cryptography is kind of in a different position, due to the vastly larger API exposed. It would feel seriously unpythonic if they tried to do buffer API only. Same goes for Python core.

Is it useful to zero out the memory of the password? Maybe. It reduces the attack surface a tiny bit against attackers that can read your memory or get access to your core dumps. If you think it is not worth the trouble, thats fine too.

Feel free to do as you find it most convenient, I'll have a look at a branch if you put it there.

behackett commented 8 years ago

@schlenk the tricky thing appears to be passing non-ascii characters in a buffer. There is no easy way to tell what format / encoding the bytes are in. How important is that to you?

behackett commented 8 years ago

Actually, I think we can support passing utf8 encoded byte strings in a buffer.

behackett commented 8 years ago

@schlenk this is implemented in master now. Let me know how it works for you.