We implemented OWASP's CSRFGuard to protect our pages in the web application. For example */myCsrfProtected.jsp. We have injected CSRF token at all occurrences of */myCsrfProtected.jsp within the application. Everything works fine.
However, we have other use case where the link to this protected page is sent out to users in an email. Think about a link to a report. Now when user clicks on this link, the token is missing or invalid and hence the CSRFGuard filter blocks the request assuming this to be a CSRF attack. (this is what filter has been implemented for :-) )
Is there any way to handle this use case and allow access to CSRF protected page from outside the application.
Ideally a CSRF token check would need to performed only for POST requests. GET requests are supposed to be idempotent((no side effects on server, just return some data no transactions performed on behalf of the user).
If all you want to do is return a report when the user clicks on link you might not need a csrf check to be performed. You might still want to make sure the user is authorised. You should be able to by pass the CSRF check for this request
Related
So, we are implementing this special kind of authorization, where after logging in, user is presented with basic dashboard. When trying to get to another location, he is asked to authorize with password.
The thing is that in order to present the basic dashboard, some requests are sent and need to come with 200 response, while the rest just returns error message and redirects to authorization screen.
To summarize, we're gonna have 3 kinds of endpoints:
- blocked, until user authorizes
- allowed to return proper data for the first time while each consecutive request will require authorization
- no authorization required
I cannot find a way to overcome the 2nd type. Is there a way to record the number of requests sent per specific endpoint? Or is there any way to actually allow first unauthorized use and then required authorization?
One way would be to authenticate user without any role the first time that users access to yours controllers.
Then when he try again to access you could sent them to login process if user is logged without role.
To securize this methods could use the annotation below:
#Secure("IsAuthenticated()==false || (IsAuthenticated() && hasRole("WRITE"))")
To securize manually a user should use the SecurityContextHolder class
We're using spring security (Authorisation and Resource server ) in our project.
client sends a token request (/oauth/token) with the oauth2 parameters.
spring security app creates a token for the user and respond to the client with the access_token, refresh_token, custom user object (name, organisation, email etc) and authorities (Roles).
Client adds additional roles (say ROLE_CLIENT, ROLE_USER).
spring application will store the above roles for the given user.
Next time when client sends a token request, spring security returns the previously created token (not expired yet) along with the user and authority information. This authority information is not having the latest roles (added in step4).
Here spring security always using the existing token (as it is not expired) and returning the valid token. Is this the expected behaviour even though the user object is being modified?
It sounds like you need to revoke the access token when the users roles change if you want the next request to get a new access token with the new roles and not return an existing token with existing roles if it's still valid.
At the point where you update the users roles you'd likely want to revoke the token.
I haven't personally tested this but I found a guide for it here https://www.baeldung.com/spring-security-oauth-revoke-tokens so your milage may vary.
I want to add that this does not sound like the normal OAuth2 process and you may be breaking a few conventions here which might bite you later. That said, you don't have to follow a standard if you're confident in your proposed solution.
Edit: To clarify the users roles and access is normally part of a resource and not part of the token exchange. For example you have a normal OAuth2 request which generates a token which you can exchange for an access token, as you've laid out in steps 1 and 2. Then you'd normally take that access token and request user access information from a resource such as "userinfo" service or something similar.
Your security service can also be a resource server but the two steps should be seen as different. Then when you want to modify the users roles you do this again through a resource. This means the next time you invoke the resource it'll have the up to date information without needing to authenticate the user again.
I am using spring and enabled csrf with HttpSessionCsrfTokenRepository, I clearly know if the client is sending the csrf token either as _csrf parameter or X-CSRF-TOKEN header for the request spring picks up the token and validates with the token which was generated using generateToken(HttpServletRequest request)
But my question is how does spring does this internally.
My reason for this question being:
1.I have a Rest POST call which takes credentials and validates the
identity of the user. But Since I want to add a csrf token to the
rest call as a layer of security I wanted to add it in the post body
to prevent csrf token leak.
So if I know how spring security filters these tokens internally it would be helpful. I revised the spring documentation but it is mostly how we can use CSRF token in a form with hidden field or meta tags and Ajax call with a header.
And I also would like to hear any comments on my design if it is good to have the token in body( I am convinced because it would not be a simple url parameter to leak the token ) or should I have it in the header. I just dont want to lean to use header just because its simple. Looking for the best solution.
Please shed some light.
There're multiple implementations for CsrfTokenRepository in spring if you want to look into into it. for eg:
https://github.com/rwinch/spring-security/blob/master/web/src/main/java/org/springframework/security/web/csrf/HttpSessionCsrfTokenRepository.java
https://github.com/rwinch/spring-security/blob/master/web/src/main/java/org/springframework/security/web/csrf/CsrfFilter.java
https://github.com/rwinch/spring-security/tree/master/web/src/main/java/org/springframework/security/web/csrf
https://docs.spring.io/spring-security/site/docs/4.2.7.RELEASE/apidocs/org/springframework/security/web/csrf/CookieCsrfTokenRepository.html
https://docs.spring.io/spring-security/site/docs/4.2.7.RELEASE/apidocs/org/springframework/security/web/csrf/CookieCsrfTokenRepository.html
IMO its good (safer - may be?) to keep Tokens on the header because of few reasons that i can think of..
You cannot set token on a body for your GET request. You want to be consistent of all your endpoints (you may not need it today but things change really fast)
Tomorrow if you want to change your Auth model, you dont want to to change your request body. when request body changes you break the contract with clients
If you change your auth model to a authorization server, you can add proxy server (like ngnix?) before your service and lets call it auth-proxy. You can leave all security related things to this auth-proxy and it will inspect the header and do the validations for you. You don't want the proxy to look into your request body and you can focus on your business implementation
Request body is completely related to your business so you can focus on it vs dealing with security related things in your body.
Everytime you create a new Request for a new endpoint you don't want to keep adding tokens in all the requests
It's just my opinion based on my experience.
I know this has been asked already, but I am not able to get it to work.
Here is what I would like to get accomplished:
I am using Spring Security 3.2 to secure a REST-like service. No server side sessions.
I am not using basic auth, because that would mean that I need to store the user's password in a cookie on client side. Otherwise the user would need to login with each page refresh/ change. Storing a token is I guess the lesser evil.
A web client (browser, mobile app) calls a REST-like URL to login "/login" with username and password
The server authenticates the user and sends a token back to the client
The client stores the token and adds it to the http request header with each api call
The server checks the validity of the token and sends a response accordingly
I did not even look at the token generation part yet. I know it is backwards, but I wanted to get the token validation part implemented first.
I am trying to get this accomplished by using a custom filer (implementation of AbstractAuthenticationProcessingFilter), however I seem to have the wrong idea about it.
Defining it like this:
public TokenAuthenticationFilter() {
super("/");
}
will only trigger the filter for this exact URL.
I am sticking to some sample implementation, where it calls AbstractAuthenticationProcessingFilter#requiresAuthentication which does not accept wildcards.
I can of course alter that behavior, but this somehow makes me think that I am on the wrong path.
I also started implementing a custom AuthenticationProvider. Maybe that is the right thing?
Can someone give me a push into the right direction?
I think pre-auth filter is a better fit for your scenario.
Override AbstractPreAuthenticatedProcessingFilter's getPrincipal and getCredentials methods.
In case the token is not present in the header, return null from getPrincipal.
Flow:
User logs in for the first time, no header passed, so no
authentication object set in securityContext, normal authentication
process follows i.e. ExceptionTranslation filter redirtects the user
to /login page based on form-logon filter or your custom authenticationEntryPoint
After successful authentication, user requests secured url, pre-auth filter gets token from header authentication object set in
securityContext, if user have access he is allowed to access secured
url
I'm using JBoss Seam 2.2 in my application, and am seeing some strange behavior in the way login failures are handled. When a user fails authentication using #{identity.login}, I see multiple JSF messages being displayed. One has the message key org.jboss.seam.loginFailed, while the other has the key org.jboss.seam.NotLoggedIn. I would obviously expect the first message, as that corresponds to entering an incorrect password. However, why is the second message being displayed? There's no reason for it. I'd like to be able to remove that from the list of messages displayed when it's not necessary, but I haven't found a way to do so. Thoughts?
org.jboss.seam.security.FacesSecurityEvents adds the org.jboss.seam.NotLoggedIn message when it observes the org.jboss.seam.security.notLoggedIn event. The org.jboss.seam.security.notLoggedIn event is raised when an attempt is made to access a resource that requires a certain level of authorization, but the user is not logged in.
After authentication fails, is the user being redirected to a protected page? Do you have any custom login logic that might be accessing a protected resource?
I suggest providing your pages.xml, components.xml, and any custom authentication logic you might have.