Search code examples
javaspringspring-bootspring-securityoauth-2.0

Does using Spring's Oauth2 InMemoryClientRegistrationRepository represent a security risk?


TL;DR: Is it ok (..against potential attacks / secured-enough) for a backend application to store sensible information in-memory in clear text (such as oauth2 token uri+credentials of external authz servers), for caching / performance optimization?


My setup: I am using Spring Boot 3 with Spring Security 6, and Spring Webflux for its webclient in order to call external web services.

I have configured my Spring Security configuration to inject an OAuth2 filter into the spring webflux.webclient in order to authenticate against external authorization servers. So far so good, everything was tested and working as expected.

My concern: When looking at my setup from a security standpoint, under the hood, Spring defaults to using "InMemoryClientRegistrationRepository" for all "[web] client [oauth2 configuration] registrations", which means that it stores in-memory all my configured oauth2 client configurations, that I ensure in the first place to be well secured when persisted, e.g. all my oauth2 credentials are strongly encrypted strings using AES/GCM in my database.

But once I read those oauth2 configs from my db (and decrypt), and send that over to Spring Webclient (through for instance ServletOAuth2AuthorizedClientExchangeFilterFunction), those oauth2 configs end up being stored by Spring in-memory, in clear text; it is easy to inject spring's "OAuth2AuthorizedClientRepository" instance in any other app bean such as any of my controller/service, to debug and see all my oauth2 credentials cached in-memory by spring (clientId, clientSecret, tokenUri, etc) in clear text, and that info. actually points to many external systems that will eventually end up be all customers'/external systems' authz servers:S ..so I absolutely need to take some good care of those credentials.

Am I right to be concerned by such in-memory caching of that oauth2 sensitive information, and should I work toward replacing it with perhaps a custom client repository that also does caching like spring for performance optimization, but at the same time encrypts at least the oauth2 client secrets before storing in-memory, to prevent some very unlikely in-memory attacks (perhaps an attack that would force app. to do some kind of thread+memory dump, to then access the memory dump on disk and get those oauth2 credentials..), or am I way over-thinking all this, and if we can't even store sensisble information in application cache/memory (which is very different than storing on disk), then it might be just better to never go out and just stay home?..!

I would appreciate some feedback from folks considering themselves great at dealing with application security in general:) What do you think?!

thanks!


Solution

  • If you look at it from another perspective, anyone able to modify your service will also have access to the key that you use to decode your encrypted database entries.

    It doesn't matter where you get your keys from, Hashicorp Vault, Kubernetes etcd (as a Secret), your service still has to have access to some kind of secret (private key, password, keytab) to access the rest of the data

    A best practice is to use files to store the secrets and not to use environment variables, don't do something like evn DB_DECODE_PASSWORD=verySecret. Put ot in a file that you can read.

    So, you either trust your runtime environment or you don't, it really is that simple.