I need to stop a user from being able to logon to my website multiple times by opening multiple browsers. I'm running coldfusion and using sessionmangement. I'm currently loading the session.cfid, timestamp and ip address into a table. I thought I could distinguish between browser instances from one another with the cfid or cftoken, but they are identical coming from the same client computer. Is there a way to distinguish between the two browser instances and kill the original? A snippet of my code is attached.
You can distinguish between the same user login on different computers or if the user launches a separate browser window (by double clicking the icon). But when the user does a FILE-> New Window or New Tab, the browser opens a second window/tab using the same session. There is nothing you can do about this.
I tried for a long time and then ultimately decided, why am I bothering? This is the browsers functionality, it cannot be changed, my bank allows it, my brokerage accounts, every secure web site I access allows it because they have no choice. (Yes, I tested them all).
So, since you can't avoid it. The question is, why do you want to? That's the only thing that can change :)
It is an honor to be featured in Gartner 2019 Magic Quadrant for Datacenter Backup and Recovery Solutions. Gartner’s MQ sets a high standard and earning a place on their grid is a great affirmation that Acronis is delivering on our mission to protect all data, apps, and systems.
I can't give you specifics, but ... suggestions to try ...
Depending on how the window / tab is opened (and probably depending on the browser) .
1) if the window / tab is opened by starting a new browser altogether, then it should get a new session ID ... especially if you use JSESSIONID rather than Application/SessionID...
2) if the window / tab is opened by "File | Open Window/Tab" then you should be able to check it, using cgi.http_referer (as this will be "" rather than "http://server/...."
3) if the window / tab is opened by "right click, and open link in new window/tab" there is no way to test for it, (except possibly since there is no "back" capability for that window)
On one system I worked on, workflow control was required ... we used a table to identify session, what the current page was, and what URL's etc were allowed ... not a nice system ... but, if the URL requested by the client did not match an acceptable one based on the previous page requested, the browser recieved a "error, please start again" result, and bounced the user back to the beginning. Definitely not nice, but it worked.
(FYI, My back used to use a similar method, and I found it EXTREMELY annoying :-)
> 1) if the window / tab is opened by starting a new browser altogether, then it should get a new session ID ... especially if you use JSESSIONID rather than Application/SessionID...
Correct - if you double click on the Browser Icon and launch a new application, this will give you a new session. This would act the same as launching from a different computer. In this case you can easily know that you have the same user with a different session and handle it with no problem.
> 2) if the window / tab is opened by "File | Open Window/Tab" then you should be able to check it, using cgi.http_referer (as this will be "" rather than "http://server/...."
Not true. The referrer is the same as the original window. When opening a new window or tab in this method, the browser makes an exact copy of the session. You will not be able to detect a difference between these two identical windows/tabs. This is the scenario that prevents the asker from meeting the requirement.
Even managing a session using hidden form fields, the URL or cookies (session or client) will not work because everything is duplicated.
> Not true. The referrer is the same as the original window. When opening a new window or tab in this method, the browser makes an exact copy of the session. You will not be able to detect a difference between these two identical windows/tabs. This is the scenario that prevents the asker from meeting the requirement.
> Even managing a session using hidden form fields, the URL or cookies (session or client) will not work because everything is duplicated
That is not entirely true ... (testing here limited exclusively to IE8/Vista/CFMX801)
Using the File menu:
* "New Tab (CTRL+T)" opens a tab using "about:tabs"
* "Duplicate Tab (CTRL+K)" opens a new tab containing the same URL, but cgi.http_referer is null.
* "New Window (CTRL+N)" opens a new window containing the same URL + cgi.http_referer.
Using the Right Click / Context Menu:
* "Open link in new tab" opens a new tab with no history (detectable by Javascript)
* "Open link in new window" opens a new window with no history (detectable by Javascript)
I honestly don't have time to test the JSESSION options
As far as "hidden form fields/URLs" etc, createUUID was unique on EVERY test even on "duplicate tab". By using a tracking database (CFToken/CFID) combined with UUID, and permissable links, it WOULD be possible. Not easy, but certainly possible.
Where as some browsers under some circumstances may provided different results, the ability to use this as a reliable means-to-the-end requires consistent and predictable results. Testing the referrer yields unpredictable results so cannot be used to reliably shutoff access.
> createUUID was unique on EVERY test even on "duplicate tab"
Yes, every time createUUID is run it does return a unique value. But the question is, what do you then do with it. How do you tell the page to create a new ID for a new session when you can't identify the session as 'new.'
> By using a tracking database (CFToken/CFID) combined with UUID
The CFToken/CFIDE and JSESSIONs are duplicated when using FILE>New Tab (the only scenario under debate). Adding UUID cannot help you because you cannot identify when to use it.
> Where as some browsers under some circumstances may provided different results, the ability to use this as a reliable means-to-the-end requires consistent and predictable results. Testing the referrer yields unpredictable results so cannot be used to reliably shutoff access.
if EVERY url contains a UUID, it is possible to use the referrer as an indicator of the previous page.
If the UUID in the referer already exists in the tracking table, but the current UUID is not in the tracking table, then the page has been regenerated (either through Refresh or New Page etc)
> Every time createUUID is run it does return a unique value. But the question is, what do you then do with it. How do you tell the page to create a new ID for a new session when you can't identify the session as 'new.'
I did not mean, use the ID for the sessionID, but for uniqueness of Page generation ... In reference of using a Page/Status tracking table, knowing the UUID of the refering page and the UUID of the link, it would be VERY easy
> The CFToken/CFIDE and JSESSIONs are duplicated when using FILE>New Tab (the only scenario under debate). Adding UUID cannot help you because you cannot identify when to use it
I wasn't attempting to give an exact answer, but give an indication of a workable method ...
How Curtis can use this is upto him. It really depends on whether or not he needs to block multiple windows, or multiple routes through the application. It also depends on whether they have control over the client software (and it's not unusual in large corporations to require specific browers)
@albrandwood, that solution does detect the new window being opened. Perhaps it could work into a solution for Curtis although it does have some unpleasant side effects.
@curtis, The principle is that the page must be drawn with a query string that matches the saved session uuid, and that session uuid changes with every page request. So, when the new window opens, the query string remains the same, but the session uuid has changed, so the result is a 'bad session.'
@
In order to implement, this uuid must be placed on every link and form submit.
The negative side effects are that you cannot use the Back button and you cannot do a page refresh. Both will result in a bad session. This would be a show-stopper for me as aborting the session because the user hits back or refresh would be a huge problem.
Here is a working version of the code for further play..
<cfparam name="session.nextuuid" default=""><cfif len(cgi.QUERY_STRING)> <cfif cgi.QUERY_STRING is not session.nextuuid> <cfset session.nextuuid=""> <h1>Error Bad Session</h1> <cfelse> <h3>UIDs Do Match!</h3> This is the matched UUID: <cfoutput>#session.nextuuid#</cfoutput><br> <cfset session.nextuuid = createuuid()> Creating a new NextUUID: <cfoutput>#session.nextuuid#</cfoutput><br> </cfif><cfelse> <cfset session.nextuuid = createuuid()> <h1>Error 2: Bad Session</h1></cfif><cfoutput><br><a href="#cgi.script_name#?#session.nextuuid#">Go to this page</a> with nextID = #session.nextuuid#<br></cfoutput>
IT issues often require a personalized solution. With Ask the Experts™, submit your questions to our certified professionals and receive unlimited, customized solutions that work for you.
Premium Content
You need an Expert Office subscription to comment.Start Free Trial