Closed bkosborne closed 8 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
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.
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
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
Yes sounds good. I'll keep thinking
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
@djoos I think the problem w/ using Doctrine's cache are outlined above
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
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.