1) When user logs into our system via SSO, we generate a random token and keep that in session at server side code looks like, so it will be generated only once just after user logs in
if(slingRequest.getSession().getAttribute("csrfToken") == null){
UUID uuidRandom = UUID.randomUUID();
String Guid = "_" + uuidRandom.toString();
log.info("Random CSRF number Generated is "+Guid);
slingRequest.getSession().setAttribute("csrfToken",Guid);
}
2) On every page , we are reading from session and keeping this value in a hidden field code looks like
<%String csrfToken="";
if(null != request.getSession() && null != request.getSession().getAttribute("csrfToken")){
csrfToken=(String)request.getSession().getAttribute("csrfToken");
pageContext.setAttribute("csrfToken",csrfToken);
}
%>
<input type="text" id="csrfToken" value="${csrfToken}" style="display:none;" name="csrfToken">
3) On every POST request we are sending this csrfToken which is stored in hidden field to server and validate it at backend with the values retrieved from session at server side, if it’s is same then request is valid otherwise it’s not.
if(csrfToken.equals(request.getSession().getAttribute("csrfToken").toString() ))
4) On logout we invalidate the session and remove the token from session.
request.getSession().removeAttribute("csrfToken");
request.getSession().removeAttribute("globalAccountHolder");
request.getSession().invalidate();
Issue:
Sometimes pagesource/hidden field value is shown as same as it was in previous session, which is before log out value. i.e step 2 shows older value and when step 3 gets executed the matches of token fails, but if we reload the page using Cntrl+R then hidden field value is shown correctly and works. So not able to understand if this is browser caching problem for a page??
Tried Solution: As a solution for this we have set no-cache in our response headers, but this doesn’t work .
Is there any other solution you can think of like including any meta-tag in page header, or some otherthing?
ALso this issue i am facing sometimes only not everytime
Related
I have set one attribute in session in the first request and retrieve by the second request but its return null while accessing from ios safari browser only.
The requests are served from JSP and getter and setter of attributes are written in Java.
In first request I set
request.getSession().setAttribute("KEY","VALUE");
In second request I get
String key = req.getSession().getAttribute("KEY");
the Key is null while accessing from IPhone Safari browser.
Please advice.
The cookies should be enabled in your browser for session/cookie functionalities to work. Please check privacy setting in the browser.
strong textI am new, need a proper way to validate. I followed
5 line code. it doent have a httpsession but still going to appointment.jsp . why so?
I followed How to check if session exists or not?
it is giving a session. org.apache.catalina.session.StandardSessionFacade#3b59e880 but the user is not login in...
it does. but I dont know why and how it got one?
if (request.getSession(false) == null) {
request.getServletContext().getRequestDispatcher("/login.jsp").forward(request, response);
} else if (request.getSession(false) != null) {
request.getServletContext().getRequestDispatcher("/appointment.jsp").forward(request, response);
}
Session is not created after your user logs in, It is created at the first request to the container from a browser. This enables container to track subsequent requests from same browser. This is implemented usually using a cookie with unique id(session id).
So even it depends on what is happening at user logout? are you calling session.invalidate().
We cant say a user as authenticated just because session object is not null.
There will always be a HttpSession object (ok, not always, but most of the time) - this is not an indicator for an authenticated user.
You need to set a session attribute eg. "authenticated" to flag this session as authenticated or not.
You can add this by calling request.getSession().setAttribute(...)
By default, a JSP will create a session. You probably don't want that behavior for your login page, so use the page directive in login.jsp:
<%# page session="false" %>
You would also need to make sure that any other JSP that is accessed before a successful login does not create a session.
if (request.getSession(false).getAttribute("userLoggedIn") != null ) {
if((Boolean)request.getSession(false).getAttribute("userLoggedIn") ) {
request.getServletContext().getRequestDispatcher("/appointment.jsp").forward(request, response);
}
} else {
request.getServletContext().getRequestDispatcher("/login.jsp").forward(request, response);
}
when a form is submited that inserts a record into the database and the operation was successful, I do a redirect and then pass some parameters in the Url to display the newly inserted record along with a header message (i.e., "Insert was successful").
response.sendRedirect(yPage + "?pid=" + ipd + "&feedback=" + form.getFormFeebackSB() );
I would then display in jsp like:
<c:out value="${param.feedback}" />
I use a redirect instead of a forward because I want the operation to be idempotent. When I used forward users who hit refresh after a successful insert most often always clicked retry on the warning popup and it resulted in duplicate inserts.
Our IT department then discovered that I had a XSS vulnerability:
page.jsp?feedback=%3Cscript%20type=%22text/javascript%22%3Ealert%28%27xss%27%29;%3C/script%3E
So I changed to this:
<c:out value="${param.feedback}" escapeXml='true'/>
but now any <br> in my FeedbackSB get escaped and I end up with a header message as such
Insert was successful<br>An email was sent to Joe<br>Now Complete the XYZ Form;
what is the standard way to pass messages back to user, while keeping any submits idempotent and protecting against XSS?
EDIT:
I searched Flash Scope and came across this http://blog.smartkey.co.uk/2011/01/implementing-flash-scope-in-java-web-applications/
Since my application would require a lot of work to incorporate a framework, the filter mentioned in that link was easy to incorporate and was able to implement flash scope with very little effort.
Don't pass the message itself in a redirect. Store the message under a unique key in the session, redirect with the key of this message as URL parameter, then go to the session, get the message, and display it.
I would also remove the message from the session immediately: if the user refreshes, there is no reason to tell him again that the insert was successful.
Most of the MVC frameworks do that for you, using what they usually call a Flash scope (session attributes that are removed from the session as soon as they've been retrieved).
i am having one jsp file with the following code
String name=request.getParameter("user");
if(name==null)
name=(String)request.getSession().getAttribute("name");
else
request.getSession().setAttribute("name", name);
i assume if the page get any request with user as parameter, it will save the value to that particular user session and in case the get request is not having any 'user' parameter it will try to read the user value from the session. The code is working perfectly when i host it from my local server(glassfish).
But when i upload it into some remote host, things are getting weird.
When i hit the page with parameter 'user', its saving the value in the session. But then again if i hit the page from some other browser(or after clearing cookie), its retrieving the previous value saved, instead of returning null
Am i doing something wrong, actually im pretty new to Java EE.
You cannot get previous value saved unless
1) Your session is not finished and same session is getting extended. Can you explain how you are clearing the cookies.
2) Are you typing the URL or trying to refresh the page after deleting the cookies.
I am having a problem of setting the data of a (persistent/cross browser session) cookie correctly inside a Servlet and the reading it in a Filter.
the code of the Servlet (running at log-in time) is:
String encodedValue = new String(Base64
.encodeBase64(req.getParameter("account").getBytes()));
Cookie cookie = new Cookie("projectAuthenticationCookie", encodedValue );
cookie.setMaxAge(24*60*60);
cookie.setPath("/");
res.addCookie(cookie);
This will get the cookie inside the response, but the when I read it within my filter with the following code:
Cookie authenticationCookie = null;
Cookie[] cookies = ((HttpServletRequest) request).getCookies();
for (Cookie cookie : cookies){
if ("projectAuthenticationCookie".equals(cookie.getName())) {
authenticationCookie = cookie;
}
}
I only get the value I set right, all other fields are either null, empty or different. Max age for example always returns -1 and thus the cookie will never persist.
I tried setting the expires-header with:
res.setDateHeader("Expires", System.currentTimeMillis() + 24*60*60*1000);
as I read that without a valid expires-header the session will timeout anyway (correct me if I am wrong), but that didn't help either...
One issue I am thinking of is that I am running on localhost (tried setting cookie.setDomain("localhost") but also no luck). My web server/serclet container is Jetty 7 but I do not think that this is relevant...
Any hints?
The fields other than name and value are not populated (and thus not meaningful) on cookies you get from a request.
These fields are intended to inform the browser about the max age; path, etc. of the cookie, but the browser doesn't send back this information to the server. The only time where it's important to have the correct max age, path, etc. is when you create a cookie and add it to the response. Use your browser to check if it stores the correct information instead of trying to find it at server-side.