djoos / EscapeWSSEAuthenticationBundle

Symfony bundle to implement WSSE authentication
http://symfony.com/doc/current/cookbook/security/custom_authentication_provider.html
137 stars 59 forks source link

Re-evaluate using a cache to store nonces #64

Closed bkosborne closed 8 years ago

bkosborne commented 9 years ago

I was just reviewing #19 and #44 and the problem of clearing old cache entries.

One problem with Doctrine cache (and it appears most cache libraries I looked at) is that there's no support for cache "bins". Seems like that would help since we'd create a bin for "wsse_nonces", and just deal with clearing that bin as needed.

It still doesn't help with clearing cache entries that are expired. It's not clear to me after reading Doctrines cache documentation how you would clear expired entries, or how Doctrine itself clears them for things like query cache.

But beyond all of that, is using a cache really appropriate for storing nonces? Caches should be able to be cleared and not really affect functionality, only performance. But if for whatever reason the whole nonce cache is dropped, there's a brief security hole in the app since a replay attack could now succeed.

Just wanted to use this thread to get my thoughts down and start a discussion.

djoos commented 9 years ago

Hi @bkosborne,

thanks for getting in touch. This is definitely an interesting topic...

We refactored the bundle a while ago to make use of the Doctrine cache so to allow different implementations to store nonces in various ways rather than the (only) previous file system (~ PhpFileCache) way.

Even though the Doctrine Cache is called "cache", we actually don't intent it being a "cache" for nonces, but the way they are persisted to (eg.) the file system or db, key-value store, etc. The big issue currently that it is not possible to clear out the expired nonces - due to limitations in the Doctrine Cache - which should be possible as opposed to clearing the whole cache, which leaves a whole for replay attacks...

Do let me know your thoughts - happy to bounce some ideas round to make this bundle better... Thanks in advance!

Kind regards, David

bkosborne commented 9 years ago

So I was wondering how cache entries that have a lifetime set get cleared, and I think it's up to the underlying cache platform to handle that. APC for instance does it when you add a new cache entry: http://php.net/manual/en/function.apc-add.php.

After looking at the code for Doctrine's PhpFileCache, there's nothing to clear old cache entries. You need to know the cache ID to even find where the cached files could possibly be. From this, seems like it's impossible to delete old entries from the PhpFileCache, only to clear the entire cache at once.

Using other cache providers like APC will likely handle the deletion of expired cache entries, but that still leaves the problem of storing this data in a cache that can be cleared. When deploying a new version of a Symfony app, a lot of people will clear the whole cache and then warm it up, perhaps using the console command cache:clear. This will clear out the nonce cache, leaving a brief security hole.

I propose we therefore abandon using the Doctrine cache entirely, and instead work on some solution to store the cache entries in persistent storage somewhere. I can work on this, but I want to get buy-in from you.

bkosborne commented 9 years ago

I think what we need is a model class for UsedNonce with properties like username, nonce, timestamp. The problem is how to abstract it's implementation to work with different persistence layers... this may help a bit: http://symfony.com/doc/current/cookbook/doctrine/mapping_model_classes.html

djoos commented 9 years ago

Hi @bkosborne,

thanks for looking into this. I'm definitely interested in digging deeper in a few weeks time when I'm back in the office.

What do you think?

Kind regards, David

bkosborne commented 9 years ago

Yes sounds good. I'll keep thinking

djoos commented 8 years ago

Hi Brian,

I finally got round looking into this. Delegating the expiration to the cache layer (Doctrine) should suffice, is there still a need to look deeper into this?

Happy to pick up the discussion if needed!

Kind regards, David

bkosborne commented 8 years ago

@djoos I think the problem w/ using Doctrine's cache are outlined above

djoos commented 8 years ago

Ok, in that case it might be something you need to take up with the people behind the Doctrine cache, to implement some currently missing features on specific cache drivers...

However, I'll close this issue for now as being out of scope for the actual WSSE Authentication bundle itself.

Thanks! David