I have a question about "session-theft" and the supporting of "deep links" in a web application, and best practice.

Our web application has a small number of front-door public web pages (e.g. /servlet/Login) and the rest of the application is considered to be private pages that can only be accessed by authenticated users. The login process results in a session being created with a random id, and then the system ensures that all links generated by the system embed this ID. So for instance, the home page which is really /servlet/Home is rendered as /servlet/@SESSION_ID@/Home. The framework checks the @SESSION_ID@ in the URL and if it doesn't exist (or doesn't match the user's session in the memory on the server) then the user gets redirected to the login page with an error, since clearly this request originated from outside the system and/or from a different session.

This technique has been in use for several years, and apart from being really annoying (you cannot bookmark anything) the idea appears to be that nobody can trick you into clicking on a link in the application that can take advantage of an authenticated session in another tab - i.e. the person crafting the link wouldn't know what the session id is, and thus can only trick you into navigating to one of the public links.

We need to be able to support "deep links" in the application now; such that a user in one application can invoke our application with a URL such as /servlet/WorkOrderDisplay?id=1234. The required behaviour is that if the user has not already logged in to our application, then they should be redirected to the login screen and after a successful login taken to the work order. However, subsequently clicking on that URL (whilst the session is active) should not send them to the login screen. Herein lies the problem - the other application doesn't (and can't) know the session id to use, so the request will always be considered an untrusted one. We could create a whitelist of trusted URLs, but I don't feel qualified enough to know if this is just creating a backdoor to circumvent the protection.

My real question though is why I don't see this technique used on other websites. How do other websites protect against this "session theft", and does our home-grown technique really enhance security? I should add that our application is akin to a CRM system rather than a Banking/Finance system - we need to balance security with usability so we cannot force every click from outside the system to go to the login screen.

Advice, links to other articles etc would be greatly appreciated.

Apologies if I've used the wrong terminology here. I've tried to Google a lot, but suspect I'm not using the right terminology, although my Googling did lead me to find https://cheatsheetseries.owasp.org/

  • In the context of users using an application, this is often called "bookmarking" rather than "deep linking" (but both communicate what you're asking about). – gowenfawr Apr 22 '20 at 14:03

What you call "session theft" sounds like cross site request forgery (CSRF). CSRF occurs when a victim is signed into a website, and then visits an external site or page with attacker-created content. The attacker's content could include form submission to the vulnerable application, possibly causing the user to send money or perform another dangerous action without their knowledge. It works because the browser will send the cookies along with the request, even if made from a different origin.

I suggest that you reference the OWASP CSRF Cheat Sheet; here's their summary of actions to take:

  • Check if your framework has built-in CSRF protection and use it
    • If framework does not have built-in CSRF protection add CSRF tokens to all state changing requests (requests that cause actions on the site) and validate them on backend
  • Always use SameSite Cookie Attribute for session cookies
  • Implement at least one mitigation from Defense in Depth Mitigations section
    • Use custom request headers
    • Verify the origin with standard headers
    • Use double submit cookies
  • Consider implementing user interaction based protection for highly sensitive operations
  • Remember that any Cross-Site Scripting (XSS) can be used to defeat all CSRF mitigation techniques!
    • See the OWASP XSS Prevention Cheat Sheet for detailed guidance on how to prevent XSS flaws.
  • Do not use GET requests for state changing operations.
    • If for any reason you do it, you have to also protect those resources against CSRF

Emphasis on the first point; this is a solved problem and there is no need to reinvent the wheel here.

  • I read that section at the weekend but failed to recognise my problem as CSRF because in my head CSRF was all about forms and post requests. Making the user navigate to a page they have permission to access isn't a big deal if it doesn't change anything I guess, which is the last point. Assuming GET operations don't change data, are there any other advantages to having this ID protection on GET operations? e.g. JavaScript in a nasty page being able to read application data via XSS? I assume if the app is vulnerable to XSS then this isn't helping? – Marcus Apr 23 '20 at 13:47
  • @Marcus yeah, XSS overrides any sort of CSRF protection anyway. You're right, as long as GET operations don't change state, there's nothing to protect against. From your question, I assumed POST requests, since that's where concern usually lies, but now I don't see what an attacker would gain in your scenario anyway. – multithr3at3d Apr 23 '20 at 14:14

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.