Click here to Skip to main content
Click here to Skip to main content

Detect and prevent multiple windows or tab usage in Web Applications

By , 28 Apr 2009
 

Introduction

In a web application development, there are various security issues that need to be addressed. One of the ASLC (Application Security Life Cycle) / RRR (Risk Residual Report) point states:

“Restrict a user to a single browser window”

HTTP is called a stateless protocol because each request is executed independently, without any knowledge of the requests that came before it. Since HTTP is stateless in nature, it has some shortcomings when it comes to the security and performance of a website. Session swapping, request-response overhead, data concurrency issues are the names of a few problems occurring due to the use of multiple windows or tabs in a web browser..

Challenges

There are two challenges in preventing multiple windows or tab usage in web applications:

  1. How can we differentiate two requests (GET or POST) at server side, whether the request originated from the same window or from tabbed/different windows?
  2. Below is a sample conversation between an HTTP client and an HTTP server running on http://www.example.com port 80.

    GET /index.html HTTP/1.1
    Host: www.example.com
  3. How can we stop the user from generating a request (GET or POST) from two tabbed/different windows at client side?
  4. Below are the sample instructions using which a user can request a tabbed/new window:

    Ctrl+N / Ctrl+T
    File->New Window / File->New Tab

    Note: All windows open from the above action share the same session/cookies when communicated with web server.

Solution to Detect and Prevent Multiple Windows or Tabs Usage in Web Applications

There are two approaches we can use in web applications:

  1. Use of window.name at client side using JavaScript.
  2. Checking the HTTP Referer header at server side.

1. Use of window.name at client side using JavaScript

Here are the details of objects/events/properties/methods used in this approach:

Objects

window The window object is the top level object in JavaScript, and contains in itself several other objects.

Events

onload Fires when the page has finished loading, including images. This is a popular event to use to run some JavaScript once everything on the page has loaded/ is available.

Properties

name The name of the window as optionally specified when calling window.open().
opener Contains a reference to the window that opened the secondary window via window.open().
top A synonym for the topmost browser window.

Methods

open(URL, [name], [features], [replace]) Opens a new browser window. The "name" argument specifies a name that you can use in the target attribute of your <a> tag. "features" allows you to show/hide various aspects of the window interface. "replace" is a boolean argument that denotes whether the URL loaded into the new window should add to the window's History list.

window.open("http://www.example.com", 
    "mywindow", "width=800px,
    height=600px, resizable=1")
close() Closes a window.

Window features in window.open()

The table below lists the string features you can pass into the "feature" parameter of window.open() to manipulate its interface. Most features support a value of true or false, though in general, simply including the name of the feature implies it should be added to the window (yes), while not including it means it shouldn't (no). Separate each feature with a comma (,).

Feature Description
channelmode Specifies if window should be opened in channel mode. IE only.
fullscreen Specifies if window should be opened in full screen mode. IE only.
height Specifies the height of the window.
left Specifies the x coordinates of the window in pixels. IE only. See "screenX" as well.
location Specifies if the location bar of the window should be included.
menubar Specifies if the menu bar of the window should be included.
resizable Specifies if window should be resizable.
screenX Specifies the x coordinates of the window in pixels. NS only. See "left" as well.
screenY Specifies the y coordinates of the window in pixels. NS only. See "top" as well.
scrollbars Specifies if window should contain scrollbars
status Specifies if the status bar of the window should be included
toolbar Specifies if the toolbar of the window (i.e., reload button) should be included.
top Specifies the y coordinates of the window in pixels. IE only. See "screenY" as well.
width Specifies the width of the window.

How does the approach “Use of window.name at client side using JavaScript” work?

In Brief

A Default.aspx page opens the Home.aspx by setting a unique window.name using JavaScript. Whenever a page is opened in other tab/window, the script checks the window.name property and redirects to the InvalidAccess.aspx page if it finds an invalid name.

In detail, step by step:

First, the Default.aspx page is requested.

*To enhance performance, we start from the Default.aspx page, as there is no extra processing at the server and client side.

On page load, the following script will execute:

<script language="javascript" type="text/javascript">
if (window.name == "default") {
    var windowFeatures ='channelmode=0, directories=0, location=1, menubar=0,
        resizable=1, scrollbars=1,status=1,titlebar=0,toolbar=0,top=0,left=0,
        width=1010,height=550';
    window.open("Home.aspx", "<%=GetWindowName()%>");
    window.opener = top;
    window.close();
}
else if (window.name == "") {
    window.name = "default";
    window.open("Default.aspx", "_self");
}
else if (window.name == "invalidAccess") {
    //alert("Invalid access. Please close
    //the window, and try again.");
    window.close();
}
else {
    window.name = "invalidAccess";
    window.open("Default.aspx", "_self");
}
</script>

And in Default.aspx.cs, we have a function GetWindowName() which returns a unique name.

public string GetWindowName()
{
  Session["WindowName"] = 
    Guid.NewGuid().ToString().Replace("-", "");
  return Session["WindowName"].ToString();
}

When the page loads the first time, the window.name of Default.aspx is blank (“”). The script sets window.name to “default” and then opens itself in the same window. Now, a unique window name (using a server side function GetWindowName()) is set, and the Home.aspx page is opened.

*It is optional to disabling the location, menubar, scrollbars, titlebar etc. when opening the Home.aspx.

The script closes Default.aspx after opening the Home.aspx page.

Note: Whenever a new window opens, window.name is blank (“”). If the window.name is blank, then Internet Explorer 7 & above shows a confirmation message:

But using the above script, it will not ask for confirmation while closing the window.

On all other pages (excluding Default.aspx), we use the following script in the Head section.

<script language="javascript" type="text/javascript">
if(window.name != "<%=GetWindowName()%>")
{
  window.name = "invalidAccess";
  window.open("InvalidAccess.aspx", "_self");
}
</script>

(The above script can be put in the Common.js file.)

And, the following code will be put in the respective code-behind file (e.g., Home.aspx.cs):

public string GetWindowName()
{
  return Session["WindowName"].ToString();
}

(The above code can be put in a common utility class which inherits from the System.Web.UI.Page class.)

2. Checking the HTTP Referer header at server side

Details of the terms used in this approach are given below.

Referer

This optional header field allows the client to specify, for the server's benefit, the address (URL) of the document (or element within the document) from which the URI in the request was obtained.

This allows a server to generate lists of back-links to documents, for interest, logging, etc. It allows bad links to be traced for maintenance.

Example:

Referer: http://www.w3.org/hypertext/DataSources/Overview.html

If a request doesn’t have referer, then it indicates that the request is not generated using options.

Ctrl + N/Ctrl + T + K & File->New Window / File->New Tab

(Please note: when opening a page in a new window or tab using a mouse right/center click, the UrlReferer property value will be available. But the window.name will be blank. And, this condition will be handled at client side using script, which we have already set.)

protected void Page_Load(object sender, EventArgs e)
{
  if (Request.UrlReferrer == null)
  {
    //UrlRererrer not found
    Response.Redirect("~/InvalidAccess.aspx");
  }
}

Conclusion

The implementation of the above two points restricts a user to a single browser window.

Note:

  • The article is based and tested for ASP.NET 2.0 and Internet Explorer 7.0, but the same concept can be applied to other technologies and browsers also.
  • It is not 100% possible to detect and prevent multiple windows or tab usage in web applications.

History

  • 24th April 2009 - Created.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

Sandeep_Rana
Software Developer (Senior)
India India
Member
No Biography provided

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
GeneralMy vote of 5memberMenon Santosh27 Feb '13 - 20:08 
Good Work
Questionwhere is this getting set Session["WindowName"] ??membersharath urs29 Oct '12 - 0:43 
where is this getting set Session["WindowName"] ??
is it in java or javascript..
 
am using jsp and servlet and javascript, please let me know how to implement the
feature here..
 
thanks in advance for replies. .
GeneralNot closing properlymembermanaf3 Aug '10 - 21:41 
Hi thanks it's realy working good ,
except for one thing after opening home.aspx
 
window.open("Home.aspx", "<%=GetWindowName()%>");
 
in FireFox ,it is not closing default page
window.close();
 
, any solution for this ???
Frown | :( :(
GeneralRe: Not closing properlymembermanaf3 Aug '10 - 22:31 
Hi ,
 
i have updated the code from
if (window.name == "default") {
window.open("Home.aspx", "<%=GetWindowName()%>");
window.opener = top;
window.close();
 
to
if (window.name == "default") {
window.name="<%=GetWindowName()%>";
window.open("Home.aspx", "_self")
window.opener = top;

 

and it's now working fine with out empty pages lefted

Smile | :) manaf Blush | :O
AnswerRe: Not closing properlymemberkhChrist6 Aug '10 - 6:35 
seems that it doesn't work in firefox
here is a long discussion about it
http://www.webdeveloper.com/forum/showthread.php?t=153088[^]
GeneralGettnig session vairable from master pagemembercodeusertest12 Jun '10 - 3:51 
how do i get the session variable windowName in the master page. it comes back as null.
GeneralClose but not exactly.memberSINEND31 Mar '10 - 8:23 
This is close but not exactly what I am looking for. What I am looking for however might not be available, since it might be consider a browser vulnerability but much needed.
 
Say a user is on a site with one window open. Will they open a new window or tab at that exact same site. The problem I have is detecting if they are viewing from two windows so I can disable the JavaScript in the second.
 
If the second windows JavaScript is not canceled out it might blurb out stuff needed for the first window and visa versa.
 
I do however want to allow multiple tab or window access to my visitors, but I can't have this JavaScript executed twice in two different windows or tabs. Plus this is a module I am distributing freely, but one simple problem. Frown | :(
 
I really can't think of anything that wouldn't be buggy.
Generalgood jobmemberArlen Navasartian18 Jan '10 - 21:21 
take my 5
 
-------
Arlen.N

General<script /> tagmemberMark Rae9 Sep '09 - 23:27 
Make sure you ignore the language=javascript element of the <script /> tag, as that has been deprecated for (at the time of writing) over THIRTEEN years!
GeneralGood WorkmemberMember 495917615 May '09 - 0:56 
Good Work Done Sandeep.
 
Noopur

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Permalink | Advertise | Privacy | Mobile
Web03 | 2.6.130516.1 | Last Updated 28 Apr 2009
Article Copyright 2009 by Sandeep_Rana
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid