Dartmouth PKI Lab
Trusted Paths for Browsers
Last modified: 04/24/03 02:41:28 PM

Mozilla with SRD (synchronized random dynamic) Boundary

-- a countermeasure for web spoofing

For more information:

What is webspoofing?
Why we think SRD boundary is a countermeasure to webspoofing?
What does it look like with a SRD boundary?
How to get the SRD feature?
How we did it?
Known bugs and What need to be improved?
SRD boundaries in Mozilla 1.0 with fixed alert bug
SRD boundaries in Windows 2000 platform

Why we think SRD boundary is a countermeasure for webspoofing?

Modern web techniques give web programmer powerful tools, XML, JavaScript, Style Sheet ... The internet is full of web design tips. Almost nothing you see in web is so unique that no one can duplicate it. So how can we prevent the user from being webspoofed?

We think it is web browser's responsibility to tell client that where indeed the web page come from. The web browser should have some kind of feature to distinguish the material which is generate from browser itself and the material which is delivered from server side. This feature should not be too distracting for normal surfing and must be unspoofable.

In our method, web browser has two kinds of windows. A window with a blue boundary is "untrusted" and a window with a brown boundary is "trusted". The material from server side would be hold in blue boundary, and the material from browser itself would be hold by brown boundary. ( We found a bug in our design. Alert window, confirm windows, prompt windows may hold a string from server side, but they are in brown windows. In order to make our definition about security or insecurity more accurate, we are designing a third kind of window which would hold this kind of special material. See what need to be improved)

The style of boundary, namely inset and outset, changes according to the result of a random number generator. Since the result of random number generator is unpredictable, the boundary style is unpredictable too.


What is it looks like with a SRF boundary?

As mentioned, the new feature which we add into browser should not be too distracting for normal surfing. Here it is : An animation of our implementation. (This mock-up also shows a partial "inner-SRD" scheme: the bars at the top of the outer window are themselves marked trusted.)

I used gifmerge to edit the gif animation. Here is a nice example.

How to get the SRD feature?

We are preparing two shell scripts, sec-border and sec-border-undo. Sec-border is for install the feature, while the undo script would take off it just in case you don't like it. You need have Mozilla source code, which can be download from mozilla.org. We target mozilla- If you run into problems when using higher versions, please let me know.(zishuang@dartmouth.edu)

Download ( avilable soon):

How we did it?

Before we touch our implementation details, let us go through some basic concepts about Mozilla architecture and gtk graphic toolkit. If you already familiar with these topics, you can jump ahead to read about our implementation.


Mozilla comes with two themes: modern and classic. When we talk about themes, we use a term "skin". What is skin? Skin is the collection of a bunch of CSS files, which define how Mozilla should look. For example, a yellow shirt with white buttons and a white shirt with red buttons, both of them are shirts, but they have different style and different color combination. Mozilla's user interface consits of items like buttons, bars etc; skin defines the style and color combination of those items. Changing skin, you can change a blue small button to be a red big button.

Mozilla use CSS ( Cascade style sheet) files to define skin, which is in the themes directory in source tree. Here is a website with more skin collections.


XUL is a XML-based User-interface Language, was specially created for the Mozilla application and is used to define its user interface.

Here is a small example, a window with a toolbar which contain two buttons.

<window id="my-window" xmlns:html="http://www.w3.org/1999/xhtml"
   <toolbar id="my-toolbar">
	  <hbox id="bar-buttons">
          <button id="back-button" label="Back"/>
          <button id="forward-button" label="Forward"/> 

Each item is implemented in C++ as an object. More information can be found here http://www.xulplanet.com/


Mozilla has a modularized structure. Each module is an XPCOM ( Cross Platform Component Object Module) object and implementes a pure virtual C++ interface. XPCOM (Cross Platform Component Object Model) is a framework for writing cross-platform, modular software.As an application, XPCOM uses a set of core XPCOM libraries to selectively load and manipulate XPCOM components. XPCOM components can be written in C, C++, and JavaScript.

A JavaScript module can directly communicate to a C++ module through XPConnect. XPConnect is a technology which allows JavaScript objects transparently access and manipulate XPCOM objects. It also enables JavaScript objects to present XPCOM compliant interfaces to be called by XPCOM objects.

The XPCOM interface is written in XPIDL(Cross Platform Interface Description Language) at first. The XPIDL file is runned through an XPIDL compiler, generate a C++ header file. The C++ header file can be implemented and inherited by other classes.

For more information http://www.mozilla.org/projects/xpcom.

GTK+ toolkit:

GTK+ is a free multi-platform toolkit for creating graphical user interfaces, primarily designed for the X Window System. Linux version Mozilla use GTK to create windows and other XUL items. They call the items as widgets.

Implementation details:

We changed the files in three directory of mozilla source tree, themes, xpfe and xpcom. In order to make SRD boundary still works when enter-SSL warning pops up, we used inter reference window.


Themes directory contains css files which describe how a <window> object looks like, a <button> looks like. There are two main subdirectories, one is classic, the other is modern. They define the two main themes mozilla carries. We only worked on modern theme, but if you prefer classic theme, you can use the same approach to achieve the same effect in it.

$MOZILLA/themes/modern/global directory contains several global css files. The most important files is global.css which defines how the <window> object look like. All other css files derive from it.

We copy the old global.css file into global2.css file and wrote our own global.css as below which imports global2.css.

/* ::::: window ::::: */

window { 
  padding: 0px;
  background-color: #C7D0D9;
  color: #000000;
  font: message-box; 
  border-color: orange;
  border-style: inset;
  border-width: 15px; /*eileen*/
window[wait-cursor] { 
  cursor: wait !important; 

window[borderStyle="true"] {
  border-style: outset !important;	

window.dialog { 
  padding: 7px 5px 5px 5px;
  border-color: orange;
  border-style: inset;
  border-width: 15px; /*eileen*/

/* :::::externalWindow ::::: */

externalwindow { 
  padding: 4px;
  background-color: #C7D0D9; 
  color: #000000;
  font: message-box;
  border-color: blue;
  border-style: inset;
  border-width: 15px; /*eileen*/
externalwindow[wait-cursor] { 
  cursor: wait !important; 
externalwindow[borderStyle="true"] {
  border-style: outset !important;	

externalwindow.dialog { 
  padding: 7px 5px 5px 5px;
  border-color: orange;
  border-style: inset;
  border-width: 15px;

@import url("chrome://global/global2.css");

In this global.css file, we added border to regular window which is orange color. We also defined a new window style called as externalwindow. The externalwindow has same border style and width, but with different color, blue. When window object's borderStyle attribute is set as true, the border style changes to be outset. If the borderstyle attribute is removed, the border style changes back to be inset.

At the end of global.css, it imports the global2.css file which is the original global.css file.

Mozilla use XUL define the user interface. Xpcom/browser/resource/content/navigator.xul is the file define the main surfing window. It is the only file with externalwindow. When server side use JavaScript open a new window, navigator.xul is called as default, so server side invoke window has blue boundary. ( We discovered an inconsistence, please see what need to be improved.) Any other window has orange window boundary.


In xpcom directory, we added a subdirectory, borderstyle. In borderstyle directory, we implemented a xpcom module, nsBorderStyleModule.

nsIBorderStyle.idl : idl file which defines the nsIBorderStyle interface
 * the nsIBorderStyle interface which provide the random value 
 * true or false. JavaScript can read the random value then set .
 * the window border style as inset or outset. 

/* nsISupports is the basic xpcom module */
#include "nsISupports.idl"

 * The uuid is a unique number identifying the interface normally
 * called IID. It can be generated as follows:
 * Windows: guidgen.exe
 * Unix: uuidgen which comes with e2fsprogs package
 * Mac: ???
 * All platform: Using irc, connect to irc.mozilla.org and type in
 *                              /join #mozilla
 *                              /msg mozbot uuid
 * 12/10/2001, we are in test, so we didn't register the uuid number
[scriptable, uuid(70ab680d-a6a9-4b6e-a3c5-18504783925a)]
interface nsIBorderStyle : nsISupports
    readonly attribute string value;

In nsIBorderStyle interface, we defined a readonly attribute string value. Readonly means this value only can be read by JavsScript, but can not be set by JavaScript. We also include the nsISupports.idl which is the essential interface of xpcom module. nsISupports interface is equivalent to COM's IUnknown interface. It takes care of interface interrogation and reference counting.

$MOZILLA/dist/bin/xpidl is the compiler for idl file. Let nsIBorderStyle.idl run through this compiler with different options.

xpidl -w -I../idl -m header nsIBorderStyle.idl generate the head file nsIBorderStyle.h
xpidl -w -I../idl -m typelib nsIBorderStyle.idl generate the typelib file nsIBorderStyle.xpt

These two files are in xpcom/borderStyle/_xpidlgen directory.

nsBorderStyleImp class is the implementation of nsIBorderStyle interface.
 * nsBorderStyle.h is the header file of nsBorderStyleImp class
 * which is a particular implementation of the nsIBorderStyle interface
 * this file is not machine generated. xpcom/sample/nsSample.h was used
 * as reference.

#include "nsIBorderStyle.h"
 * using uuidgen generated a unique identify which hopefully doesn't
 * conflict with other uuid.
 * CID for this class is 
 * {478803ab-c024-43e4-a8ff-7a339d486185}

{ 0x478803, 0xc024, 0x43e4, { 0xa8, 0xff, 0x7a, 0x33, 0x9d, 0x48, 0x61, 0x85} }

#define NS_BORDERSTYLE_CONTRACTID "@mozilla.org/borderstyle;1"

class nsBorderStyleImpl : public nsIBorderStyle
  virtual ~nsBorderStyleImpl();

   * This macro expands into a declaration of the nsISupports interface.
   * Every XPCOM component needs to implement nsISupports, as it acts
   * as the gateway to other interfaces this component implements.  You
   * could manually declare QueryInterface, AddRef, and Release instead
   * of using this macro, but why?

   * This macro defined in nsIBorderStyle.h
   * NS_IMETHOD GetValue(char * *aValue);

   * function generateValue is used for generating random numer 0 or 1
  void generateValue();
   * function to set Value according the randome generator
  void setValue();

  char * mValue;
  int randomNumber1;  // a number to remember the old random number
  int randomNumber2;  // a number to hold the randome generator result
  time_t t1;          // used to record current time.  

nsBorderStyleImp class inherit the public funtion of nsIBorderStyle, GetValue, also has two private functions, generateValue and setValue. GenerateValue is the random number generator function. It is called by setValue(), which check the random number and set the string which can be read by JavaScript.

 * nsBorderStyle.cpp 
 * file implements nsBorderStyle.h

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include "plstr.h"
#include "nsBorderStyle.h"
#include "nsMemory.h"

  mValue= PL_strdup("false");     /* initate mValue as false*/
  randomNumber1 =0;
  randomNumber2 =0;          

  if (mValue)

 * NS_IMPL_ISUPPORTS1_CI is a macro which is defined in
 * nsISupportsImpl.h#740, not in #700, the lxr result is wrong!
 *  #define NS_IMPL_ISUPPORTS1_CI(_class, _interface)    
 *   NS_IMPL_ADDREF(_class)                                              
 *   NS_IMPL_RELEASE(_class)                               
 *   NS_IMPL_QUERY_INTERFACE1_CI(_class, _interface)     
 *   NS_IMPL_CI_INTERFACE_GETTER1(_class, _interface)
NS_IMPL_ISUPPORTS1_CI(nsBorderStyleImpl, nsIBorderStyle);

 * Notice that in the protoype for this function, the NS_IMETHOD macro was
 * used to declare the return type.  For the implementation, the return
 * type is declared by NS_IMETHODIMP
 * this function's implementation is as same as in nsSample.cpp
NS_IMETHODIMP nsBorderStyleImpl::GetValue(char * *aValue)

  /* if the timeNow is bigger than t1, that means a new random number need be generated.*/
  if (time(NULL)>= t1)

    NS_PRECONDITION(aValue != nsnull, "null ptr");
    if (! aValue)
        return NS_ERROR_NULL_POINTER;

    if (mValue) { 
         *aValue = (char*) nsMemory::Alloc(PL_strlen(mValue) + 1);
        if (! *aValue)
            return NS_ERROR_NULL_POINTER;

        PL_strcpy(*aValue, mValue);
    else {
            *aValue = nsnull;
    return NS_OK;

void nsBorderStyleImpl::generateValue()
  unsigned char foo; // foo hold the unsigned char value which read out from 
                     // "/dev/random" 
  int count;
  int fd; 

  fd = open("/dev/urandom", O_RDONLY);
  if (-1 == fd) {

  count = read(fd, &foo, 1);

  if (count != 1) {

  randomNumber2= (int)foo%10/5;

  printf("\n #############the new random number is: %d\n", randomNumber1);


void nsBorderStyleImpl::setValue()
   * setValue is called by getValue, so we are not brother by infinite loop which need
   * a seperate thread.

        if( randomNumber1 != randomNumber2)
	      /* the border style has to be changed in this situation 
	       * record the new randomNumber is randomNumber 1 for next 
	       * cycle use.
	      randomNumber1= randomNumber2;
	      if (mValue)
	      if ( randomNumber1 ==0)
		  mValue = PL_strdup("true");
		    mValue = PL_strdup("false");

GenerateValue function use Linux kernel random number generator /dev/random. According to Secure Programming for Linux and Unix HOWTO, this random number generator gathers environmental noise from device drivers and other sources into an entropy pool. When accessed as /dev/random, random bytes are only returned within the estimated number of bits of noise in the entropy pool (when the entropy pool is empty, the call blocks until additional environmental noise is gathered). When accessed as /dev/urandom, as many bytes as are requested are returned even when the entropy pool is exhausted.

More information about RNG see http://www.cs.berkeley.edu/~daw/rnd/

Every time a thread checks the mValue, BorderStyle module compare current time with t1. If current time is bigger than t1, setValue is called and ask for a new random number from generatValue. If the new generated random number is different from the old one, the mValue is reset.
At the end of setValue, we set t1=time(NULL)+2. Every 2 seconds, a new random number is generated.If you prefer a longer interval, you can set it as 5 seconds or so.

nsBorderStyleModule.cpp is the factory class of nsBorderStyleImp.

The new borderStyle directory need to be added into xpcom/Makefile, in order to be compiled.


Xpfe directory contain the xul files which describe how the XUL iterms are arranged in browser windows. The xul files also have linke to js files, which contain JavaScript functions. There are four subdirectories of xpfe. The main surfing window is defined in /xpfe/browser/resource/content/navigator.xul. All other xul files describe the accessory windows, like bookmarks, history, preference etc.

We want all accessory windows have orange boundary and the main surfing window has blue boundary. So we change <window> tags in navigator.xul to be <externalwindow>,those accessory xul files still contain <window>. Each xul file hook up corresponding changeBorder.js file by adding
< script type="application/x-javascript" src="chrome://navigator/content/$Filename-changeBorder.js">
in certain place. $Filename is the xul file name.

Let's take a look of navigator-changeBorderStyle.js as an example. Navigator.xul contain a externalwindow "main-window".

  * a Javascript file which change the window boundary style 

var style = Components.classes["@mozilla.org/borderstyle;1"].getService(Components.interfaces.nsIBorderStyle);

function change()
	window.setInterval("changeAttr()", 500)

var mainWindow;
function changeAttr()
	mainWindow = document.getElementById("main-window");
	if (style.value=="true")
		mainWindow.setAttribute("borderStyle",true );
	}else {
JavaScript need ask PrivilegeManager for the privilege to use xpconnect. Please read www.mozilla.org/scriptable/ for more information. The change function is called in window onload event. Every 500 milliseconds, changeAttr function is called to check the mValue in BorderStyleModule and do the attribute operations.You can change the interval millisecond number to affect the performance.

All the new changeBorder.js files need be included into certain jar.mn files in order to be packed into jars. Different directory has its own jar.mn, so it is a time-consuming task. We are going to provide a shell script which can do all the work automatically for you.

Reference Window:

Some modules are singleton services in whole Mozilla. When one thread is accessing the XPCOM module, all other threads are blocked. Enter-SSL warning window use nsPrompt service which is one of the singleton services. When a enter-SSL warning window pops up, all other threads are blocked. All other windows stop responding and become inactive. We want to keep at least one window is active in this situation as a reference for the synchronization.

We let broderStyle module fork a new process, which use GTK+ toolkit create a reference window. When a new random number is generator, borderStyle module would inform the reference process. The reference window changes its image according to the random number to indicate the border style.

Here is the GTK+ program. The idea is create a window with a viewport. Viewport is a widget which contains two adjustment widgets. Changing these two adjustments' scale enable to allow the user only see part of the window. The viewport also contains a table which contains two images, one stands for inset, the other stands for outset. When random number is 1, we set the adjustment scale to show the inset image; when the random number is 0, we show the outset image.

 /* reference window is the window pop up by borderstyle module.
 * so when enter_ssl warning window blocks all other threads,
 * the reference window still be active to provide the right border
 * style reference for the user.
 * a gtk program compiler with
 * gcc -o reference_window reference_window.c `gtk-config --cflags --libs`
 * in order to let execl work, you have to start mozilla process 
 * by entering ./dist/bin/
 * then start mozilla by ./mozilla

#include <gtk/gtk.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>

/* viewport has two adjustments */ 
GtkObject *adj1, *adj2;

 * call back function for window close
 *  window close will terminate the process
gint close_application( GtkWidget *widget,
                        GdkEvent  *event,
                        gpointer   data )

 * callback function for monitoring pipe. 
 * Pipe's writing end is borderStyle module.
 * This is pipe's reading end 
 * read out from pipe and adjust the window viewport
static void input_callback( gpointer data, gint fd, 
			    GdkInputCondition condition)
  int n;
  char line[10];
  char *true="true\0";
  char *false="false\0";
  /* read out from pipe, we used dup2 map fd[0] with STDIN_FILENO
   * so here, we read from STDIN_FILENO
  n = read(STDIN_FILENO, line, 20);
  if (strncmp( (char*)&line, true, 5) >0)
     gtk_adjustment_set_value( (GtkAdjustment *)adj2, 245.0 );
      gtk_adjustment_set_value( (GtkAdjustment *)adj2, 0.0 );

/* the main function for create the window */
void creat_window(void)
  int i, j;
  GtkWidget *window;
  GtkWidget *view; 
  GtkWidget *table;
  GtkWidget *picture_left;
  GtkWidget *picture_right;
  GdkPixmap *right_image_pixmap;
  GdkPixmap *left_image_pixmap;

  /* GdkBitmap for structures of type GdkPixmap,*/
  GdkBitmap *mask_left; 
  GdkBitmap *mask_right; 
  GtkStyle *style;
  /* create a new window*/
  window = gtk_window_new (GTK_WINDOW_DIALOG);
  /* limit window size*/
  gtk_widget_set_usize(window, 145, 130);
  /* after link to this singal, window close will treminate the process*/
  gtk_signal_connect( GTK_OBJECT (window), "delete_event",
                        GTK_SIGNAL_FUNC (close_application), NULL );
  /* window border width set*/
  gtk_container_set_border_width( GTK_CONTAINER (window), 2 );

  /* Create a 1x3 table */
  table = gtk_table_new (3, 1, TRUE);

  /* now for the pixmap from gdk */
  style = gtk_widget_get_style( window );
  /* get the GdkPixmap from the file.*/
  left_image_pixmap = gdk_pixmap_colormap_create_from_xpm( window->window,
	       NULL, &mask_left, &style->bg[GTK_STATE_NORMAL], "./left.xpm");
  right_image_pixmap = gdk_pixmap_colormap_create_from_xpm( window->window,
	       NULL, &mask_right, &style->bg[GTK_STATE_NORMAL], "./right.xpm");

  /* get the Gtk image widget from the pixmap, */
  picture_left = gtk_pixmap_new ( left_image_pixmap, mask_left);
  picture_right = gtk_pixmap_new ( right_image_pixmap, mask_right);

  /* Insert picture_left into the upper left quadrant of the table */
  gtk_table_attach_defaults (GTK_TABLE(table), picture_left, 0, 1, 0, 1);
  /* Insert picture_right into the down left quadrant of the table */
  gtk_table_attach_defaults (GTK_TABLE(table), picture_right, 0, 1, 2, 3);

  /* create two adjustments for viewport */
  adj1 = gtk_adjustment_new (0.0, 0.0, 101.0, 1, 10.0, 10.0);
  adj2 = gtk_adjustment_new (0.0, 0.0, 101.0, 1, 10.0, 10.0);
  /* create the viewport */
  view = gtk_viewport_new( (GtkAdjustment *)adj1, (GtkAdjustment *)adj2 );

  /* let viewport contain the table */
  gtk_container_add (GTK_CONTAINER (view), table);

  /* let the window contain the viewport */
  gtk_container_add (GTK_CONTAINER (window), view);

  gtk_widget_show  (window);
  gtk_widget_show  (view);
  gtk_widget_show  (table);
  gtk_widget_show  (picture_left);
  gtk_widget_show  (picture_right);

  /* monitoring IO, when the pipe is ready for reading,
   * input_callback is called

  gdk_input_add( STDIN_FILENO, GDK_INPUT_READ, 
		 input_callback, NULL  );

int main( int argc, 
	  char * argv[])
  gtk_init(&argc, &argv); 

The constructor of NsborderStyleImp class fork a new process to run the reference window process.

  mValue= PL_strdup("false");
  randomNumber1 =0;
  randomNumber2 =0;
  /* create a pipe */
  if (pipe(fd)<0)
    printf("pipe error\n");

  /* start a new process to run  gtk program */
  if ( (pid = fork())<0)
    printf("fork error\n");

  else if (pid >0){   /* parent process generate random number */
    write(fd[1],"false\n", 6);
  else{               /* child process */

    close(fd[1]);     /*close child process' write end. */

      if (fd[0] != STDIN_FILENO){
       if (dup2(fd[0], STDIN_FILENO) != STDIN_FILENO)
    	printf(" dup2 error\n");
       close( fd[0]);

   /* start to run the gtk program */ 
   if ( execl("./referenceWindow/reference_window", 
              "./referenceWindow/reference_window", NULL) <0)
     printf(" execl error\n");

    /* exit child. note the use of _exit() instead of exit() */

Known bugs and What needs to be improved?

As borderStyle is a singleton service, when one thread is accessing the BorderStyle Module, the other threads are blocked. So no two threads can do the attribute operation at the exact same time. The window boundaries change sequentially, however we can divide each changing cycle clearly.

The access to /dev/random would not return if the entropy pool is empty. When one thread is in BorderStyle module, all other threads are blocked. If the accessing thread doesn't return quickly, it slows down the whole browser performance.

As signed JavaScript can ask for privilege to access XPConnect. When it does, the browser would pop up window ask the user, whether he grants this privilege to this JavaScript. If he doesn't, the JavaScript can not use XPConnect. However, if he does, there is possibility that a signed JavaScript can spoof our trusted boundary.

As mentioned above, server JavaScript also can pop up alert windows, prompt windows and confirm windows which hold a string from server. So far, they like other common dialog windows having brown boundaries. However, because the server string is untrusted material. In order to strictly enforce the trusted-untrusted model, we need distinguish server pop up windows from other common dialog windows.

Mozilla added one feature into window.open, called "chrome". When server pop up window uses window.open("test.html", "chrome"), this command would return an empty window without any boundary. "Chrome" keyword is letting server control the window chrome, not using browser default chrome. Because server may be able to forge brown boundary in this empty window, so far, we define the trusted boundary as synchronized brown boundary. And brown boundary without synchronization can not be define as trusted.

We are working on fixing these problems.

If you have any questions, please send mail to me.
eileen zishuang ye

Back to Dartmouth PKI Lab demonstrations Maintained by Zishuang (Eileen) Ye, eileen@cs.dartmouth.edu