Share And Enjoy - Cycle Stealing with Java

David Purdue
SunSoft Pacific
PO Box 362
Artarmon, NSW, 2064
Email: David.Purdue@Aus.Sun.COM

Abstract

The Java programming language has gained great popularity, and the main use to which it is being put is the creation of Applets that can be downloaded into a WWW page.

There are two features of Java that must be used to make applets useful. They are multithreading and the ability to open a network connection to the server from which the applet was loaded. Without these features it will be very difficult to create Applets that have good interactive response, or are able to do useful work.

However the combination of these features can lead to a denial of service attack on Java capable WWW browsers. I will show that this attack is not of great concern, and can actually be used as an effective way of sharing the computer resources in an organisation.
Keywords: java, security, attacks, denial, service, share, resources

1 Introduction

Java has swept the net and has also been the topic of several security concerns.

In this paper I will look at a possible denial of service attack that arises out of two features of Java that can not easily be removed. I will show why this attack is not a great cause for concern, and may even lead to a solution to one of the fundamental problems in operating system design.

2 What Is Java?

This may seem a trite question. Given the amount of coverage Java has received in the media, in journals and on the net, most readers should have a good idea of what Java is.

However, for the purpose of this paper I want to be explicit about what Java is and how it is used. For that purpose, Java is two things:

2.1 How Java Is Used

Although Java is a general purpose programming language - much like C or C++ - the main use it has been put to, and the use that has garnered most of the hype, is the creation of small programs - called 'Applets' - that can be downloaded over the Internet and run within the confines of a World Wide Web browser. (Cornell & Horstmann 1996, p.10) This use has a couple of implications...

The question to ask is, 'What is so useful about a program downloaded into a Web page?' This may be inverted to read, 'What features must a program have to make it useful in the context of the WWW?'.

Consider that one of the main selling points of the WWW is that it provides an interactive way to explore the myriad information available on the Internet. The particular appeal of browsers such as Mosaic and Netscape is that they give a graphical user interface to the 'net. Therefore any downloadable programs we expect to run in those browsers should extend this interactivity, and provide better and more responsive user interfaces than ordinary WWW pages.

In addition, if we want these downloadable programs to do anything more than brighten up a Web page with some animation (which these days can be done just with GIF files anyway), then we must provide a way for these programs to have a memory. For example, if a word processing program cannot remember your document from one session to the next, then it is just a typewriter.

But providing this memory is fraught with danger since it can lead to giving access to your system to code that is not trusted. The problems inherent in this are described in 'Mobile Code Security', presented at this conference. (Brown 1996) The response of the Java designers was to require that systems that download and execute applets impose the Java Security Model on those applets.

2.2 The Java Security Model

Java applets are quite restricted in what they are allowed to do. A full description of the restrictions are given in several references (for example, (Flanagan 1996, ch. 14)), but in summary:

3 Multithreading

The designers made multithreading a feature of Java because 'the benefits of multithreading are better interactive responsiveness and real-time behaviour' (Gosling & McGilton 1996).

I would go further to say that multithreading is almost an essential part of creating interactive graphical user interfaces. To see why, examine the following example.

The Bounce application presents the user with two buttons: 'Start' and 'Close'. When the user presses 'Start', a black ball starts bouncing around the screen - it moves 1000 times and stops. The code for Bounce is shown in Appendix I.

The Bouncing Ball Application Screen

The trouble with Bounce.java is that it is single threaded. This means that while the program is bouncing the ball around the screen, it can't think about anything else - like processing mouse clicks. So if you tire of seeing the ball bounce around the window and wish to close the window, that's tough. You must wait until the ball has finished bouncing before the next click on the close button will be recognised.

I have seen this effect in many X Windows programs. As soon as you ask the program to go fetch something from a remote database, the whole GUI freezes up until the remote database responds.

Fortunately, in Java this is easy to fix because multithreading is very easy to implement in a Java program. A multithreaded version of Bounce, BounceThread, is shown in Appendix II, with the differences between Bounce.java and BounceThread.java shown in Appendix III. All we have really done is turn the Ball object in to a subclass of Thread. This means that the Java Virtual Machine will execute Ball's 'run' method in a separate thread, leaving the thread running the Bounce object's 'main' method free to handle interaction with the user.

This has a side effect though. In this version of the program, the 'Start' button can be hit as often as desired. Each time it is hit, a new Ball object is created, allocated a thread, and starts running. Thus, it is possible to have many balls roaming the screen at once:

The Multithreaded Bouncing Ball Application Screen

In summary, it pays to note that almost any object can be allocated a thread by subclassing the object from the Thread class, making sure it has a 'run' method that does something useful, and getting someone to call its 'Start' method.

4 Networking

Like multithreading, networking in Java is quite easy. Although there are a number of interfaces, all networking can be done via the Socket object.

Appendix IV shows an applet that contacts the host it was downloaded from and asks it what the time is, giving a result similar to this:

The time at my server is Sun Aug 18 10:00:34 1996

You would expect networking to be easy in a language system that is supposed to tie together the Internet. And, in fact, if all you are doing is fetching URLs, the networking code becomes even easier.

Note that applets in particular must be able to access the network if they are to have a memory. This is because of the security restrictions outlined above - remember, an applet cannot touch your local file system.

5 Putting Them Together

By combining the features of networking and multithreading, it is possible to create an applet that will make use of your computing resources in a way that is useful to the applet writer.

There are many problems in computing that can be split into an arbitrary number of pieces to take advantage of however many CPUs are available. For example, rendering a scene in computer graphics or cracking a key by brute force in cryptography.

By creating a Java applet that spawns a thread to do work for the server and then sends the results back to the server over a socket connection, the computer running the Web browser can contribute to the calculation the server is performing.

Here is an example of how it would work. Say I wanted to calculate a region of the Mandlebrot set. I could create a thread that would take as arguments the y value for a row, the start x, end x and delta x values for the points to be calculated. The thread would then send back values for pixels until it reached the end of its row, or it was terminated (possibly by the user going to another page).

Meanwhile, the server would keep track of which parts of the image had been drawn and which applets were connected. As new applets were connected, the server would send them an unfinished part of a row to do. The more applets that were connected, the faster the server would generate its image.

Note that time constraints prevented me from constructing this example, but in principle it is not difficult.

6 Why Is This Significant?

You are probably saying to yourself, 'So what? Everyone knows that Java is a huge security hole anyway'.

However, if you look at the security problems in Java that have received all the hype - CERT 1996a, CERT 1996b, Dean et al. 1996, Home Page Press 1996a, Home Page Press 1996b - you will note that they are caused by bugs in the implementation of the Java Virtual machine, and not by flaws in the Java security model.

My point is that you cannot prevent someone taking advantage of your CPU without turning off one of these very desirable features of Java. As noted above, if you take out multithreading, then performance of applets goes down and you get worse interactive behaviour. If you remove networking, even by blocking communications with a firewall, then you are limited in how useful you can make applets

7 Should I Be Worried?

In short, no.

The worst attack that someone can launch against you is to waste your CPU cycles. But since you were 'surfing' the Web, they probably were not doing anything useful anyway.

Another consideration is that, as an applet programmer, there are two ways I could waste your CPU cycles. I could use these features to get the applet to do useful work for myself, or I might just be a very bad programmer (likely, since I am writing Web content) and write inefficient Java code. As a user of my applet, it would be hard for you to tell the difference.

There are some examples on the Web of hostile applets that purposely burn up CPU and/or memory - a denial of service attack (Javasoft 1996). The Java developers are aware of this and are developing means to restrict an applet's resource usage. However, they face a fundamental problem. As they put it, 'It is hard to automatically tell the difference between a hostile applet and an MPEG viewer'.

8 Share And Enjoy

There is a positive slant to the exploitation of multithreading and networking shown here. It can be used to allow access to otherwise idle resources.

Most organisations arrange their computing resources these days on the Workstation Model. Every user has their own computing resource on their desk, connected via a network so that resources such as printers, file servers or computer servers can be shared. A problem with this model that has been the subject of considerable amounts of research is that few people make 100% use of their workstation - they spend many hours away from their desks, and even when at their desks they may not be using the computer (Tanenbaum 1992, ch. 12). How do we make use of these idle workstations?

One approach is taken by operating systems such as Amoeba or Plan 9. Taking the slogan 'the network is the computer' to its logical extreme, these systems treat every computing device on the network as a resource that can be applied to whatever workload is pending.

The trouble with this approach is that it is too socialist: 'From each CPU according to its cycles - to each process according to its code'. The reason the managing director has the biggest computer is that, although it spends 99.97% of its time in the idle loop, when the MD does want it, he gets very fast response. He would not get this response if he was sharing it with others.

Others have tried a user level approach to this, for example, the Pratt & Whitney 'SuperComputer At Night' programme, where every workstation is devoted to complex numerical analysis problems from 5 p.m. to 9 a.m. (Mackay 1996), and the TreadMarks system (Amaza et al. 1996). The problem with these systems is that the user's workstation is taken out from under her, whether she is still using it or not.

Wouldn't it be nice if you could say when others could use the CPU power of your workstation, and even choose which projects could use it?

Well, by using these features of Java, that is exactly what you can do. Create a Java applet that contributes towards some large calculation, then to share your computer - when you want to - simply load the appropriate web page into a browser. When you no longer wish to share your CPU, just close down the browser.

9 Conclusions

There are features of Java that make a denial of service attack possible - basically, people can steal your CPU cycles.

It is difficult to solve this problem and prevent this attack, because the features involved are very useful themselves, and it is difficult to tell a malicious applet from one that just needs a lot of resources.

However, while this can be used as an attack, it could also be used as a way of sharing the computer on your desktop when you are not using it.

Bibliography

1
Amza, C. et al. (1996) TreadMarks: Shared Memory Computing on Networks of Workstations, IEEE Computer, 29(2):18-28.

2
Brown, L. (1996) Mobile Code Security, in AUUG'96 & Asia Pacific World Wide Web 2nd Joint Conference Proceedings, AUUG Incorporated and Charles Sturt University, Melbourne.

3
CERT (1996a) CERT Advisory CA-96.05 - Java Implementations Can Allow Connections to an Arbitrary Host, Computer Emergency Response Team.
URL: ftp://cert.org/pub/cert_advisories/CA-96.05.java_applet_security_mgr

4
CERT (1996b) CERT Advisory CA-96.07 - Weaknesses in Java Bytecode Verifier, Computer Emergency Response Team.
URL: ftp://cert.org/pub/cert_advisories/CA-96.07.java_bytecode_verifier

5
Cornell, G. & Horstmann, C. S. (1996) Core Java, SunSoft Press, Java Series, Mountain View, California.

6
Dean, D., Felton, E. W. & Wallach, D. S. (1996) Java Security: From HotJava to Netscape and Beyond, Department of Computer Science, Princeton University, Princeton, New Jersey.
URL: http://www.cs.princeton.edu/sip/pub/secure96.html

7
David Flanagan (1996) Java In A Nutshell, O'Reilly and Associates, Nutshell Handbooks, Sebastopol, California.

8
Gosling, J. & McGilton, H. (1996) The Java Language Environment, White Paper, Sun Microsystems Incorporated, Mountain View, California.
URL: http://java.sun.com/doc/white_papers.html

9
Home Page Press, Inc. (1996a) Deadly Black Widow on the Web: Her Name is JAVA, Online Business Consultant.
URL: http://www.hpp.com

10
Home Page Press, Inc. (1996b) Java: Be Afraid; Be Very Afraid, Online Business Consultant.
URL: http://www.hpp.com

11
JavaSoft - A Sun Microsystems Inc. Business (1996) Java Security - Denial of Service.
URL: http://java.sun.com/sfaq/denialOfService.html

12
Mackay, S. (1996) SuperComputer At Night, SunSoft, Interview with Pratt & Whitney CIO - Internal videotape.

13
Tanenbaum, A. S. (1992) Modern Operating Systems, Prentice-Hall, Englewood Cliffs, New Jersey.


Appendix I - Bounce.java

From (Cornell & Horstmann 1996, ch. 12).
/*
 * Gary Cornell and Cay S. Horstmann, Core Java (Book/CD-ROM)
 * Published By SunSoft Press/Prentice-Hall
 * Copyright (C) 1996 Sun Microsystems Inc.
 * All Rights Reserved. ISBN 0-13-565755-5
 *
 * Permission to use, copy, modify, and distribute this
 * software and its documentation for NON-COMMERCIAL purposes
 * and without fee is hereby granted provided that this
 * copyright notice appears in all copies.
 *
 * THE AUTHORS AND PUBLISHER MAKE NO REPRESENTATIONS OR
 * WARRANTIES ABOUT THE SUITABILITY OF THE SOFTWARE, EITHER
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
 * PARTICULAR PURPOSE, OR NON-INFRINGEMENT. THE AUTHORS
 * AND PUBLISHER SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED
 * BY LICENSEE AS A RESULT OF USING, MODIFYING OR DISTRIBUTING
 * THIS SOFTWARE OR ITS DERIVATIVES.
 */

/**
 * @version 1.00 07 Feb 1996
 * @author Cay Horstmann
 */

import java.awt.*;

public class Bounce extends Frame
{  public Bounce()
   {  setTitle("Bounce");
      canvas = new Canvas();
      add("Center", canvas);
      Panel p = new Panel();
      p.add(new Button("Start"));
      p.add(new Button("Close"));
      add("South", p);
   }

   public boolean handleEvent(Event evt)
   {  if (evt.id == Event.WINDOW_DESTROY) System.exit(0);
      return super.handleEvent(evt);
   }

   public boolean action(Event evt, Object arg)
   {  if (arg.equals("Start"))
      {  Ball b = new Ball(canvas);
         b.bounce();
      }
      else if (arg.equals("Close"))
         System.exit(0);
      else return super.action(evt, arg);
      return true;
   }

   public static void main(String[] args)
   {  Frame f = new Bounce();
      f.resize(300, 200);
      f.show();
   }

   private Canvas canvas;
}

class Ball
{  public Ball(Canvas c) { box = c; }

   public void draw()
   {  Graphics g = box.getGraphics();
      g.fillOval(x, y, XSIZE, YSIZE);
      g.dispose();
   }

   public void move()
   {  Graphics g = box.getGraphics();
      g.setXORMode(box.getBackground());
      g.fillOval(x, y, XSIZE, YSIZE);
      x += dx;
      y += dy;
      Dimension d = box.size();
      if (x < 0) { x = 0; dx = -dx; }
      if (x + XSIZE >= d.width) { x = d.width - XSIZE; dx = -dx; }
      if (y < 0) { y = 0; dy = -dy; }
      if (y + YSIZE >= d.height) { y = d.height - YSIZE; dy = -dy; }
      g.fillOval(x, y, XSIZE, YSIZE);
      g.dispose();
   }

   public void bounce()
   {  draw();
      for (int i = 1; i <= 1000; i++)
      {  move();
         try { Thread.sleep(10); } catch(InterruptedException e) {}
      }
   }

   private Canvas box;
   private static final int XSIZE = 10;
   private static final int YSIZE = 10;
   private int x = 0;
   private int y = 0;
   private int dx = 2;
   private int dy = 2;
}

Appendix II - BounceThread.java

From (Cornell & Horstmann 1996, ch. 12).
/*
 * Gary Cornell and Cay S. Horstmann, Core Java (Book/CD-ROM)
 * Published By SunSoft Press/Prentice-Hall
 * Copyright (C) 1996 Sun Microsystems Inc.
 * All Rights Reserved. ISBN 0-13-565755-5
 *
 * Permission to use, copy, modify, and distribute this
 * software and its documentation for NON-COMMERCIAL purposes
 * and without fee is hereby granted provided that this
 * copyright notice appears in all copies.
 *
 * THE AUTHORS AND PUBLISHER MAKE NO REPRESENTATIONS OR
 * WARRANTIES ABOUT THE SUITABILITY OF THE SOFTWARE, EITHER
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
 * PARTICULAR PURPOSE, OR NON-INFRINGEMENT. THE AUTHORS
 * AND PUBLISHER SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED
 * BY LICENSEE AS A RESULT OF USING, MODIFYING OR DISTRIBUTING
 * THIS SOFTWARE OR ITS DERIVATIVES.
 */

/**
 * @version 1.00 07 Feb 1996
 * @author Cay Horstmann
 */

import java.awt.*;

public class BounceThread extends Frame
{  public BounceThread()
   {  setTitle("BounceThread");
      canvas = new Canvas();
      add("Center", canvas);
      Panel p = new Panel();
      p.add(new Button("Start"));
      p.add(new Button("Close"));
      add("South", p);
   }

   public boolean handleEvent(Event evt)
   {  if (evt.id == Event.WINDOW_DESTROY) System.exit(0);
      return super.handleEvent(evt);
   }

   public boolean action(Event evt, Object arg)
   {  if (arg.equals("Start"))
      {  Ball b = new Ball(canvas);
         b.start();
      }
      else if (arg.equals("Close"))
         System.exit(0);
      else return super.action(evt, arg);
      return true;
   }

   public static void main(String[] args)
   {  Frame f = new BounceThread();
      f.resize(300, 200);
      f.show();
   }

   private Canvas canvas;
}

class Ball extends Thread
{  public Ball(Canvas c) { box = c; }

   public void draw()
   {  Graphics g = box.getGraphics();
      g.fillOval(x, y, XSIZE, YSIZE);
      g.dispose();
   }

   public void move()
   {  Graphics g = box.getGraphics();
      g.setXORMode(box.getBackground());
      g.fillOval(x, y, XSIZE, YSIZE);
      x += dx;
      y += dy;
      Dimension d = box.size();
      if (x < 0) { x = 0; dx = -dx; }
      if (x + XSIZE >= d.width) { x = d.width - XSIZE; dx = -dx; }
      if (y < 0) { y = 0; dy = -dy; }
      if (y + YSIZE >= d.height) { y = d.height - YSIZE; dy = -dy; }
      g.fillOval(x, y, XSIZE, YSIZE);
      g.dispose();
   }

   public void run()
   {  draw();
      for (int i = 1; i <= 1000; i++)
      {  move();
         try { Thread.sleep(5); } catch(InterruptedException e) {}
      }
   }

   private Canvas box;
   private static final int XSIZE = 10;
   private static final int YSIZE = 10;
   private int x = 0;
   private int y = 0;
   private int dx = 2;
   private int dy = 2;
}

Appendix III - Context diff: Bounce.java to BounceThread.java

8 lines out of 104 lines of code are changed. However, note that 4 of those are due to changing the name 'Bounce' to 'BounceThread', and one is changing the delay in the loop from 10 to 5 msec. Hence only 3 changes were needed to introduce multithreading.


*** Bounce.java	Sat Aug 17 16:18:22 1996
--- BounceThread.java	Sat Aug 17 16:18:46 1996
***************
*** 26,34 ****
  
  import java.awt.*;
  
! public class Bounce extends Frame
! {  public Bounce()
!    {  setTitle("Bounce");
        canvas = new Canvas();
        add("Center", canvas);
        Panel p = new Panel();
--- 26,34 ----
  
  import java.awt.*;
  
! public class BounceThread extends Frame
! {  public BounceThread()
!    {  setTitle("BounceThread");
        canvas = new Canvas();
        add("Center", canvas);
        Panel p = new Panel();
***************
*** 45,51 ****
     public boolean action(Event evt, Object arg)
     {  if (arg.equals("Start"))
        {  Ball b = new Ball(canvas);
!          b.bounce();
        }
        else if (arg.equals("Close"))
           System.exit(0);
--- 45,51 ----
     public boolean action(Event evt, Object arg)
     {  if (arg.equals("Start"))
        {  Ball b = new Ball(canvas);
!          b.start();
        }
        else if (arg.equals("Close"))
           System.exit(0);
***************
*** 54,60 ****
     }
  
     public static void main(String[] args)
!    {  Frame f = new Bounce();
        f.resize(300, 200);
        f.show();
     }
--- 54,60 ----
     }
  
     public static void main(String[] args)
!    {  Frame f = new BounceThread();
        f.resize(300, 200);
        f.show();
     }
***************
*** 62,68 ****
     private Canvas canvas;
  }
  
! class Ball
  {  public Ball(Canvas c) { box = c; }
  
     public void draw()
--- 62,68 ----
     private Canvas canvas;
  }
  
! class Ball extends Thread
  {  public Ball(Canvas c) { box = c; }
  
     public void draw()
***************
*** 86,96 ****
        g.dispose();
     }
  
!    public void bounce()
     {  draw();
        for (int i = 1; i <= 1000; i++)
        {  move();
!          try { Thread.sleep(10); } catch(InterruptedException e) {}
        }
     }
  
--- 86,96 ----
        g.dispose();
     }
  
!    public void run()
     {  draw();
        for (int i = 1; i <= 1000; i++)
        {  move();
!          try { Thread.sleep(5); } catch(InterruptedException e) {}
        }
     }
  

Appendix IV - RemoteDate.java

import java.io.*;
import java.net.*;
import java.awt.*;
import java.applet.*;

/**
 *
 * A demonstration of Java Applet networking.
 *
 * @author David Purdue, SunSoft Pacific
 * @version 1.0 12 Aug 96
 * @see java.net.Socket
 */

public class RemoteDate extends Applet
{
    private static final int DAYTIME_PORT = 13;
    private String time_there;

    public void init()
    {
        try
        {
            Socket sock
	        = new Socket(this.getCodeBase().getHost(), DAYTIME_PORT);
            DataInputStream is = new DataInputStream(sock.getInputStream());
            time_there = is.readLine();

            sock.close();
        }
        catch (IOException e)
        {
	    this.showStatus("Error: " + e);
        }
    }

    public void paint(Graphics g)
    {
	g.drawString("The time at my server is " + time_there, 10, 30);
    }
}


Organised by: AUUG'96 & CSU Return to Conference Proceedings