Secure Coding Compliance Assessment Session state must be managed - java

A new corporate policy on Secure Coding was recently put into effect. The initial audit assessment tagged me deficient for:
Session state must be managed such that a session will withstand replay-attacks.
I'm not exactly sure what this statement means or why I am defecient in it. I'm developing a Java Web application and set a session as such:
session.setMaxInactiveInterval(36000);

Session state must be managed such that a session will withstand replay-attacks.
The statement is way too confusing. Rewording it would yield:
The session management framework must protect the application against replay of session IDs.
It is less confusing (hopefully), and continues to carry the same meaning as the former (again, hopefully).
Typically, if one were to implement a home-grown session management framework instead of relying on the one provided by the container for instance, then it is quite possible that the session management feature of the application would be susceptible to a replay attack.
A session replay attack would involve the scenario where the session ID is replayed back in a request, after the session has expired. A well written session management framework would recognize that the provided session ID is not a valid session ID. However, there have been instances where a vulnerable session management framework accepted the now-expired session ID, and recreated the contents of the session. In worser scenarios, the session management framework did not destroy the session at all, on session expiry, resulting in the scenario where a session ID replay resulting in requests being processed.
It must be remembered that even normal users of the application may unintentionally perform session-replay attacks, if they are able to browse to protected pages in the application without logging in. This is an indication of a failure in the authentication and the session management features of the application, for the app should ideally allow users to browse protected pages only after successful authentication, which would yield a token (a session ID) that may be used for a certain duration to access the site without further authentication. If you are using persistent cookies for authentication, you may have unintentionally introduced a hole.
Going by the above, one can protect any application from session replay attacks by:
Ensure that you are using the container provided session management features. From the use of the session.setMaxInactiveInterval I would assume that you are it. But, to be sure, verify if you are creating session IDs using other means, or for that matter, verify if you are using identifiers that are equivalent to session IDs. In simpler words, ensure that your application relies only on the value of the JSESSIONID cookie (or the equivalent as configured in the container) to communicate session IDs to the browser. Also, verify if persistent cookie are in use (refer the above posted scenario).
Invalidate the session after a certain idle period. If you do not invalidate the session, then an attacker has a larger time window to brute force the session ID. From the point of view of session-replay attacks, this is worse since the attacker can replay back a compromised session ID at any point in time, and still get access to a valid user session. You would also want to revisit the duration specified in the session.setMaxInactiveInterval for the value you are using currently is 10 hours. I would consider that to be insecure. Most applications do not require a rolling window of session expiry beyond 30 minutes, with 10 minutes being the value recommended for high-value apps.
Destroy the server-side session and it's contents on expiry. In a servlet container, this is typically done by invoking session.invalidate() in a logout page/link. Ensure that you have provided users with a link to logout from the application in the first place, so that the logout request can be processed to invalidate the session using the before-mentioned API call. If you do not perform this activity, the server-side session object will be destroyed only on session expiry (which will occur after 10 hours of inactivity by the user; now you see why 10 hours is a bad idea).

this is to do with something similar to session hijacking.. where the auth token is held by a hacker to login at a later stage..
in my projects i've added a simple filter which does the following.
every jsp page which is responded would be given an attribute called id (the token is generated using UUID().. the same token is placed in the session..
when a page is posted, the filter (which is configured to filter all requests) checks for the equality of these tokens & proceeds only if the values match.
we also added a timestamp in the session & the database, whenever a page is submitted we check the time stamps in the session with the db.. if the number is within 10 ms then the request passes, else the user is redirected...

Related

Spring Session JDBC not respecting Expired Attribute

Trying to integrate Spring Session into a grails app. Successfully have gotten the sessions to persist on the back end and now I am looking at trying to manually expire sessions.
The problem is when I expire a session manually as shown below. I am not logged out of the application. Further more, when I interrogate the session object, it thinks that it is not expired.
Am I doing something wrong?
// Gets my user
def user = ctx.springSecurityService.getPrincipal()
// Gets my current session
SpringSessionBackedSessionInformation session = ctx.sessionRegistry.getAllSessions(user, false)[0]
// Expires my session (Can see change in database)
session.expireNow()
// returns false. When I look at the code for the method it is only checking if the session has
// expired due to a timeout
session.session.isExpired()
I tried looking through the docs on Spring Session for Expiry and didn't see anything for JDBC specifically. Thought I'd post it to see if anyone out there is well versed in Spring Session.

Hibernate Contextual sessions

What's the difference between ManagedSessionContext and ThreadLocalSessionContext both has a ThreadLocal in their implementation for maintaining sessions
ThreadLocalSessionContext - It takes care of the hibernate session management activities like :
Creating a session if one doesn't already exist.
Binding the session to the ThreadLocal, so that sessionFactory.getCurrentSession() returns this bound session and unbinds it once the transaction is completed.
Flush and close the session at the end of transaction complete.
ManagedSessionContext - Responsibility of session management activities like above are handled by some external entity (generally some form of interceptor, etc).
In both the cases the session is stored in the ThreadLocal though.
But the call to bind/unbind of the session and especially when to call flush and close on the session are defined via the external entity.
This gives more flexibility, for example, in the case of ThreadLocalSessionContext, the session is closed automatically when the transaction ends and it is not possible to leave the session open for multi-request conversation type of requirements.
In case of ManagedSessionContext, we can implement multi-request conversation (a.k.a session-per-conversation model) the same session needs to be kept open and should be reused across the user requests. So in the first user request we insert/update/delete some entities and in the next request we do some more operations and finally at the end of third interaction we want to commit the data.
Quoting from Managing the current Session section
When a conversation starts, a new Session must be opened and bound with ManagedSessionContext.bind() to serve the first request in the conversation. You also have to set FlushMode.MANUAL on that new Session, because you don’t want any persistence context synchronization to occur behind your back.
All data-access code that now calls sessionFactory.getCurrentSession() receives the Session you bound.
When a request in the conversation completes, you need to call Managed-SessionContext.unbind() and store the now disconnected Session somewhere until the next request in the conversation is made. Or, if this was the last request in the conversation, you need to flush and close the Session.
To represent that pictorially,
Session scoping with ThreadLocalSessionContext
Session scoping implemented for Session-per-conversation using ManagedSessionContext
You can go through the Listing 11.5 of this link for a sample implementation an interceptor that manages the session for session-per-conversation model.

Maintaining a transaction flow using Jersey REST

I am pretty new to the REST world and we are trying our hands at migrating our application to a REST based architecture. We are working on a proof of concept and we need to come up with a working proof that what we are set to achieve can be done using REST.
In our architecture, the front end screens would use Angular and would call REST services to open up a customer session and perform/maintain transactions within that session and when the session is complete, the session details (i.e. all the customer transactions within the customer session) would be sent over for commit to the DB. We only want to write to the DB after customer completes all transactions within a session. In other words, a commit to the DB happens only when the session ends.
I am hoping to get some directions on how best to perform the below steps in our Java classes.
1) Browser initiates a request to open a new customer session. A session POST service is used to generate a new session ID. The session ID is sent back as response to the browser.
Question --> What is the best way to maintain this session ID value in my Java classes?
2) Customer transactions are performed within the session. For each transaction processed a transaction POST service is used to save the transaction information along with the session information.
Question --> In my Java classes what is the best way to maintain this transaction information and how best do I associate this transaction information with the session information that was created by the previous session POST information? The client would maintain the session ID but on the service side I need to be able to map the transaction with the session ID so that I can send back a combined session payload that includes session information and the transaction within that session.
3) A customer can perform some more transactions and each transaction performed would be a transaction POST request which would have to get associated with the session id created before. Each additional transaction performed would have to be associated to the session id on the service side such that when I do a GET on the session id, I need to get the session details along with all transactions within that session.
4) Finally when the session is complete the information from the session and the session payload on the service side (along with all the transactions) will commit to the DB.
I am just looking for some general guidance on how best to do this using my Java classes and Jersey REST.
Any pointers would be appreciated.
Thanks
Ali.
Basically this question isn't easy and requires a lot of writing, however I'll try to reply.
First of all remember that REST is stateless - it means that there's no session and client needs to be authorized with every request. This is a separate topic but a nice authorization method in REST is JSON Web Token.
Secondly REST is about nouns - not verbs. Thus you should avoid URLs like /session/{sessionId}/close/ but try to model the domain using nouns and default HTTP operations: POST (create), PUT (update), GET (read), DELETE (remove).
I guess that session and transactions is just an abstraction I will show you how to model it on an example of shopping cart. In all examples I doubled the URLs - with /users/{userId}/ prefix to show you can refer to resources in many different ways
Create a shopping cart (creating a session)
POST /shopping-carts/
POST /users/{userID}/shopping-carts/
Request: may be empty or should contain necessary details about the cart
Response: must contain a newly-created shoppingCartID
{
"shoppingCartID": "1qaz2wsx"
...
}
Add an item to a shopping cart (create a transaction)
POST /shopping-carts/{shoppingCartID}/items/
POST /users/{userID}/shopping-carts/{shoppingCartID}/items/
Request: contains details about an item being added
Response: returns a newly-added item along with its unique ID
Pay for the shopping cart (commit the transactions)
POST /payments/
POST /users/{userID}/payments/
Request: must contain a shoppingCartID
{
"shoppingCartID": "1qaz2wsx"
...
}
Response: Contains details about newly-created payment
{
"paymentId": "3edc4rfv"
...
}
I know that this is a general answer but it's difficult to give a precise answer for such a wide question.
EDIT (after a discussion in comments)
In my opinion the DB should be used to keep the transactions in a temporary table before they are approved. Even if you don't want to use a DB any other persistent store is highly recommended - imagine what could happen in case of a server restart when transactions are not approved, you will lose all the data.
The options I see:
In memory. You can write a simple in-memory structure with a synchronized access. In the most simple case just plain old HashMap will be enough. Mind the fact that keeping data this way is risky, the can be erased very easily.
Use file system. If you don't want to use DB you can use file system to keep the transactions data while they're uncommitted. After adding a new transaction it's written to a file. On commit file is read and all transactions are saved to DB. A synchronized file access is also very important here. When it comes to data format you can use JSON, XML, even plain java serialization.
The last idea that comes to my head is to use an in memory DB, such as Redis. The data will be erased on a system reboot so they're less likely to be deleted, however this is not safe in my opinion as well. Such DB is much easier to use/maintain than traditional DB.
It all depends what are you trying to implement. I can't imagine a scenario where uncommitted transactions can be simply removed and nothing happens - it seems that there's a must for persistent storage. However the ideas above might be useful as well.

How ensure authentication with AJAX functions? Currently using Java Bean for authentication

I have a web app that uses a Java Bean for login functions right now and all of the JSP pages check the Bean to make sure the user is logged in. I am also introducing some AJAX functionality now with servlets and I see that of course those exchanges don't check authentication. I'm wondering how I should handle this. For example, I don't want someone to be able to logout, hit back button, then submit something with the AJAX functions successfully.
I can't access the bean from the servlet to check the login (totally wrong context and static vs non-static). I guess I could set a flag with the user entry in the database table denoting logged in or not. Then I can detect timeout logoffs and update the flag as well. But that way would require extra database accesses every time something is done. It would duplicate functionality in some way, but I guess I could perhaps use that just for the AJAX stuff. One difference with that would be the user would not be able to be logged in on multiple places at once as currently.
How is this kind of thing normally done?
Thanks for any help!
You could use session to store that flag instead of the database, and when the user logs out you should remove that flag and destroy the session. In login method
HttpSession session = req.getSession(true);
session.setAttribute("loggedIn",true)
And in your AJAX code
if(eq.getSession(true).getAttribute("loggedIn")==true)
doWork();
else
error("not logged in");
The webcontainer will handle timeouts for you, keep track of each user and his session, and so on.
But I would recommend that you use a standard for managing authntication

Generating Own Session Id in JSF

I have a web application in which we use JSF framework.
I have been diving deep into the security part for web application and hence I was looking to generate my own unique session ID(using encryption algorithm and assign it to every new session which gets created once user logs in.
Can anyone please guide me on how to set manual generated session id in session and ensure with each request that session id is transmitted.
Thanks.
I really doubt you'll generate session IDs that are more secure than the ones generated by the container, but here's what you could do, without using any container-specific extension.
Create a servlet filter which intercept every request to the server.
When a request comes in, check if a session already exists for this request (using getSession(false)). If one exists, then extract your specific cookie MY_SESSION_ID from the request, and compare its value to the one that is stored in the session. If they don't match, reject the request.
If the session doesn't exist, then create it (using getSession(true)), generate your super-secure session ID, store it as a session attribute and add the cookie MY_SESSION_ID to the response.
This has the disadvantage of creating a session automatically, even if it's not strictly needed. But that's the case most of the time when using JSPs of component frameworks.
Attempting to do this at the JSF application layer is unlikely to be successful; I would perform this task at a lower level API. I am assuming a servlet container.
I can think of two approaches:
do this at a container level via a server-specific SPI (if one even exists)
do this by rewriting requests/responses via a servlet Filter
There is insufficient information to comment on the viability of the first approach.
In the second, you would have to determine the name of the session cookie (it is usually JSESSIONID, but does not have to be). Your API would:
map the filter to all application requests
maintain a map of container session ids to "secure" ids
use the filter to rewrite any session cookie in the request with the session id
use the filter rewrite any session cookie in the response with the secure id
use a listener to remove invalid sessions from the map to avoid memory leaks

Categories