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

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!

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.

Related

Handling user authentication using SSO

I am having difficult integrating with SSO with my web application.
I have an sample dropwizard application.
I tried integrating with google and facebook open connect.
I thought of 2 approaches for integration
1. fetch the token from frontend js once the user is authenticated using open id, pass that token to the dropwizard server as cookie.
2. fetch the token from the dropwizard server itself and store the set token in cookie while responding to the frontend.
I am not sure on which of the above 2 is best or is there any recommend way of integrating with the open connect in dropwizard?
I like delegating SSO to well known applications/ libraries specific for the job. Keycloak is the application I’m familiar with. But I suppose some of the points below are application independent. This partial answer is a possible direction of a solution, but I don’t think it’s the recommended way, if there is any such way. Some people will dislike the approach.
The front end is responsible for authentication. But it cannot be trusted to be unmodified since it is in user space. Therefore calls to the back end should be validated for validity and authorization (which should be a back end task anyway).
Keycloak has libraries for well known front and back end implementations that allow easy integration. I’ve used it successfully with Angular and Dropwizard.
Integration with various identity providers can be combined. Therefore it is probably a pretty safe bet for a situation where authentication demands are expected to change. It takes some getting used to the extra layer though, so your mileage may vary.
Some links:
https://www.keycloak.org
https://www.npmjs.com/package/keycloak-angular
https://www.keycloak.org/docs/latest/securing_apps/index.html

How to load-balance Spring UsernamePasswordAuthenticationFilter when on different server

I am currently developing a REST-application which needs to be very scalable. From what I have learned about load balancing, one should split up the actual application into independent parts. So far I've separated creating accounts and the login from the actual application. I followed this tutorial to implement JWT. Is that best practice or can this solution be improved?
However, I have my actual REST-application as a separate project. Obviously, these two applications need to work together. How can I accomplish that? Is there a way to store the Token & access it in the second application?
Someone told me to follow microservice architecture according to this tutorial.
I really appreciate your help!
With the JWT pattern as described in that auth0 blog, the services are designed to be stateless. In fact, the example code explicitly disables the Spring session. All information required for authorization are fully contained in the JWT token itself and cryptographically protected.
Therefore, there is no need to store or share the token between multiple services / applications, as long as they are all configured with the same SECRET. Each load balanced service simply needs to verify the token received by the client, using the JWTAuthorizationFilter class.
From a best practice perspective, instead of "manually" issuing JWT tokens from each service, consider using an oauth2 or OpenID Connect service. This can be your own service, or you can use a 3rd party service such as auth0 or okta. (OpenID Connect is an extension to oauth2).
You can read more about oauth2 from https://auth0.com/blog/securing-spring-boot-apis-and-spas-with-oauth2/

Spring REST service, register user, authentication

Our project consists of Java back end(spring web application) and iOS and Android client applications. Now we need to add an authentication for client applications to Java back end. The idea is to register user for the first time using an external web service. At this step user provides full credentials(login and "big" password) and chooses some PIN for further authorization. After that primary step is complete successfully, user should be able to authenticate using his login and PIN(which he chose previously himself). Those login and pin should be stored in our DB. We should also be able to destroy that "session" and PIN whenever is necessary. We expect web application to have up to 10 000 registered users with up to 1000 users being online simultaneously.
We also don't plan to use any separate Authentication server, we plan to embed security into web application(back end) itself.
I've been investigating 2 different approaches. First is usual spring #EnableWebSecurity approach. This seems pretty straight forward, but some people say it will create "sessions", which are bad for the server. Session will consume lots of memory, and overall impact on performance will be bad. Is it true?
The other approach is to use Spring Oauth2 implementation. I didn't have time to study it properly, this seems to be a little bit of an overkill to me. Is it worth to study for our needs? (we are running out of time btw).
I also need to have some proper DB sctructure for the security needs.
So the question is, what is the best approach for our situation? Are there any open source projects, solving similar issue? I would appreciate any help.
Thank you.
Whatever technology you use for authentication, you will require sessions to maintain the state of authenticated user. You can use Spring security alone or with Oauth2 .
I'll suggest for simplicity you can go with Spring Security with Token functionality.
However you can find an good blog over Spring Security and Oauth.
Securing REST Services with Spring Security and OAuth2
For more clarification you can also visit here
Sessions should only take up allot of memory if you were to store large amounts of data in the session. So long as you don't do that there won't be any problem. You will need to make your own authentication decision based on your acceptable levels for security and user experience, there is no one 'right' answer. Spring security and sessions have already been talked about here How can I use Spring Security without sessions?.

What is the right way to make Spring boot authentication for mobile clients?

I need to make simple CRUD application with user registration and authentication using Spring boot, but I have some trouble figuring out how to do this right. I have created user table at RDMS and set up Redis for storing user sessions as explained here.
At Spring boot docs it's said that
If Spring Security is on the classpath then web applications will be
secure by default with ‘basic’ authentication on all HTTP endpoints.
But I defined several CrudRepository intefaces and after starting my application I can GET it's data using browser without authentication. I thought that it should work out of the box without additional tuning and therefore checked if Spring Security is on the classpath with gradlew dependencies command and it appears to be there:
Also default user password that should be displayed during application start up does not show up. So maybe I am missing something here?
Also I am not sure if that would be the best option for mobile app because it possibly uses short-living tokens. There are several other options, among which using a WebView and cookies (as was recommended by Google long ago), creating a custom authentication entry point, using approach that was used in Angular web app and finally stateless authentication with OAuth 2.0. Directly in opposite to author of Angular web app tutorial who claims
The main point to take on board here is that security is stateful. You
can’t have a secure, stateless application.
So how do we need to pass token? How long should it live? Do we need to make additional XSRF token or not? Should we use out of the box solution or implement own one? Can we make it stateless?

How to implement single sign on across multiple JVM based applications using Spring Security

I am currently trying to implement a single sign on solution across multiple JVM based (Grails, Servlets) web applications currently all deployed in the same servlet container (currently Tomcat, but don't want to limit my solution to just Tomcat). All web applications share a common database.
I've looked at various options from using CAS or other third party libraries to creating a new web service to handle Single Sign On, but none seem to really satisfy the business. My current implementation involves creating a new jar library which has a common implementation of AuthenticationProviders, and Pre-Authentication Filters based on Spring Security.
In this approach I have multiple AuthenticationProviders (currently Active Directory, and Database) for the application to authenticate against. Upon successful authentication a row would be inserted in a session table that contains the user, an expiration time, and a token. The token would be also stored as a cookie on the user's machine and that would be used to validate they have a current session in the Pre-Authentication Filters.
Having never done this before I want to make sure I'm not creating a huge security problem, and I'd also like to know what I would need to create the token? At this point a simple GUID seems to be sufficent?
Currently we are working on Spring Security 3.0.x, and haven't upgraded to 3.1 yet.
Thanks in advance.
I ended up solving this problem by doing the following:
I created a AuthenticationSuccessHandler which would add a cookie to the user's session which had identifying information as well as the hostname to try to secure it as much as possible. (The application was running internally at most customer sites so the risks here were determined to be minimal, but be careful about cookie jacking.)
Then on each application that needed to have SSO I implemented a AbstractPreAuthenticatedProcessingFilter, and placed in before the authentication filter which would pull the cookie out and create an Authentication object. Lastly I created an AuthenticationProvider which validated the information from the cookie.
Hopefully that helps someone else in the future for this type of request.
There are extensions available for KERBEROS, OAuth and SAML available on the Spring Security Extensions website. Here is the blog entry which provides an example: SpringSource Blog
If you are using NTLM as your SSO Provider, take a look at the jespa-spring project.
Or you might want to look at the Java Open Single Sign-On Project

Categories

Resources