Security problems when loading JDK1.2 Beta 4 classes in browsers

Raghunandan Havaldar (rhavaldar@str.com)
Fri, 21 Aug 1998 12:41:12 -0500

From: "Raghunandan Havaldar" <rhavaldar@str.com>
To: <jdk-comments@java.sun.com>, <java-security@java.sun.com>,
Subject: Security problems when loading JDK1.2 Beta 4 classes in browsers
Date: Fri, 21 Aug 1998 12:41:12 -0500

This is a multi-part message in MIME format.

------=_NextPart_000_0080_01BDCD00.FB02CA00
Content-Type: multipart/alternative;
boundary="----=_NextPart_001_0081_01BDCD00.FB0BF1C0"

------=_NextPart_001_0081_01BDCD00.FB0BF1C0
Content-Type: text/plain;
charset="iso-8859-1"
Content-Transfer-Encoding: quoted-printable

Hello all,

I have come upon an unexpected problem dealing
with security when loading JDK1.2 beta 4 classes
in the browsers - Communicator and IE. I am using the
Java Plugin for loading the JDK1.2 runtime.

Here's a brief explanation of the problem, and what
is suspect is the reason. I have not been able to solve
it as yet. If any of you have expereinced something
similar or can provide any tips. it would be warmly
welcomed. Thank you.

I have also attached the three related files for inspection.

I am the 'swing' part of the JDK 1.2 beta 4 for GUI. Actually,
just dealing with tree-related classes mainly. The LogBrowserApplet
class is the main applet which renders the GUI. Initially, based
on certain XML data, a tree is generated. Then, depending on
the user's choice, the tree is modified and then displayed.

The problem occurs when loading the applet itself. All the classes
can be loaded and used (inclluding the classes developed by me).
When I try to create an instance of 'TreeConverter' class, I hit the
security-related error (Verify error). I guess this has to do with the
loading of the 'TreeConverter' class. If i skip referencing this class,
I do not have a problem. But, there is nothing obvious about this
security problem.

The details follow:

About to generate a tree viewer ...
java.lang.VerifyError at
com.deluxe.deps.billing.log.browser.LogBrowserApplet.generateTreeViewer(L=
ogB
rowserApplet.java:190)
at
com.deluxe.deps.billing.log.browser.LogBrowserApplet.setDisplay(LogBrowse=
rAp
plet.java:128)
at
com.deluxe.deps.billing.log.browser.LogBrowserApplet.init(LogBrowserApple=
t.j
ava:36)
at
com.deluxe.deps.billing.log.browser.LogBrowserApplet.<init>(LogBrowserApp=
let
.java:31)
at sun.applet.AppletPanel.createApplet(AppletPanel.java:462)
at sun.applet.AppletPanel.runLoader(AppletPanel.java:398)
at sun.applet.AppletPanel.run(Compiled Code)
at java.lang.Thread.run(Thread.java)

The TreeConverter class is a simple class which a set of
java.util.* classes to store and sort objects. Some of us
feel that the exception might be due to the way the 'util' classes
are implemented. The java.util.Vector could be the reason.

There seems to be no another 'direct' reason why we encounter this
problem. I have also attached the files defining Node class and
TreeConverter class for reference and inspection.

I can get back with more explanation if desired.

Thanks
Raghu.
rhavaldar@str.com

------=_NextPart_001_0081_01BDCD00.FB0BF1C0
Content-Type: text/html;
charset="iso-8859-1"
Content-Transfer-Encoding: quoted-printable

<!DOCTYPE HTML PUBLIC "-//W3C//DTD W3 HTML//EN">

Hello all,

I have come upon an unexpected problem = dealing
with=20 security when loading JDK1.2 beta 4 classes
in the browsers - = Communicator=20 and IE. I am using the
Java Plugin for loading the JDK1.2=20 runtime.

Here's a brief explanation of the problem, and = what
is=20 suspect is the reason. I have not been able to solve
it as yet. If = any of you=20 have expereinced something
similar or can provide any tips. it would = be=20 warmly
welcomed. Thank you.


I have also attached the three = related=20 files for inspection.


I am the 'swing' part of the JDK 1.2 = beta 4 for=20 GUI. Actually,
just dealing with tree-related classes mainly. The=20 LogBrowserApplet
class is the main applet which renders the GUI. = Initially,=20 based
on certain XML data, a tree is generated. Then, depending = on
the=20 user's choice, the tree is modified and then displayed.

The = problem=20 occurs when loading the applet itself. All the classes
can be loaded = and used=20 (inclluding the classes developed by me).
When I try to create an = instance of=20 'TreeConverter' class, I hit the
security-related error (Verify = error). I=20 guess this has to do with the
loading of the 'TreeConverter' class. = If i skip=20 referencing this class,
I do not have a problem. But, there is = nothing=20 obvious about this
security problem.

The details = follow:

About=20 to generate a tree viewer ...
java.lang.VerifyError=20 at
com.deluxe.deps.billing.log.browser.LogBrowserApplet.generateTreeVi= ewer(LogB
rowserApplet.java:190)
at
com.deluxe.deps.billing.log.= browser.LogBrowserApplet.setDisplay(LogBrowserAp
plet.java:128)
at<= BR>com.deluxe.deps.billing.log.browser.LogBrowserApplet.init(LogBrowserAp= plet.j
ava:36)
at
com.deluxe.deps.billing.log.browser.LogBrowser= Applet.<init>(LogBrowserApplet
.java:31)
at=20 sun.applet.AppletPanel.createApplet(AppletPanel.java:462)
at=20 sun.applet.AppletPanel.runLoader(AppletPanel.java:398)
at=20 sun.applet.AppletPanel.run(Compiled Code)
at=20 java.lang.Thread.run(Thread.java)

The TreeConverter class is a = simple=20 class which a set of
java.util.* classes to store and sort objects. = Some of=20 us
feel that the exception might be due to the way the 'util' = classes
are=20 implemented. The java.util.Vector could be the reason.

There = seems to be=20 no another 'direct' reason why we encounter this
problem. I have also = attached the files defining Node class and
TreeConverter class for = reference=20 and inspection.

I can get back with more explanation if=20 desired.

Thanks
Raghu.
rhavaldar@str.com


=

 
------=_NextPart_001_0081_01BDCD00.FB0BF1C0-- ------=_NextPart_000_0080_01BDCD00.FB02CA00 Content-Type: application/octet-stream; name="LogBrowserApplet.java" Content-Transfer-Encoding: quoted-printable Content-Disposition: attachment; filename="LogBrowserApplet.java" /** * LogBrowserApplet.java */ package com.deluxe.deps.billing.log.browser ; import java.awt.event.WindowListener ; import java.awt.event.WindowAdapter ; import java.awt.event.WindowEvent ; import java.awt.Dimension ; import java.net.URL ; import java.net.URLConnection ; import java.io.InputStream ; import java.util.Vector ; import com.sun.java.swing.JApplet ; import com.sun.java.swing.JFrame ; import com.sun.java.swing.JList ; import com.sun.java.swing.JSplitPane ; import com.sun.java.swing.event.ListSelectionListener ; import com.sun.java.swing.event.ListSelectionEvent ; public class LogBrowserApplet=20 extends com.sun.java.swing.JApplet=20 implements com.sun.java.swing.event.ListSelectionListener { public LogBrowserApplet () { // empty constructor // can be used as both a Java Application and // Java Applet System.out.println ("About to start initialization ...") ; this.init () ; System.out.println ("Completed initialization!") ; } public void init () { this.setDisplay () ;=09 System.out.println ("Completed setting up of display") ; } public static ConfigParser getConfigParser () { return (ConfigParserInstance) ; } public void valueChanged(ListSelectionEvent event) { if (event.getValueIsAdjusting()) { return; } else { JList itemsList =3D (JList)event.getSource(); String selectedItem =3D (String)itemsList.getSelectedValue () ; this.setSelectedItem (selectedItem) ; =09 System.out.println ("Value selected =3D " +=20 this.getSelectedItem ()) ; this.cloneTree () ; this.generateTreeViewer () ; this.setTreeViewerPane () ;=09 System.out.println ("Reset to new view ") ; } } public static void main (String[] args) { JFrame browserWindow =3D new JFrame ("Log Browser") ; WindowListener windowListener =3D new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } }; browserWindow.addWindowListener(windowListener); =09 LogBrowserApplet browserApplet =3D new LogBrowserApplet () ; browserWindow.setSize (400, 600) ; browserWindow.getContentPane ().add ("Center", browserApplet); browserWindow.pack(); browserWindow.show(); } =09 // private members and methods private static ConfigParser ConfigParserInstance =3D null ; private com.sun.java.swing.JSplitPane LogSplitPane =3D null ; private LogTree LogTreeInstance =3D null ; private TreeConverter TreeConverterInstance =3D null ; private TreeViewer TreeViewerInstance =3D null ; private CriteriaViewer CriteriaViewerInstance =3D null ; private java.util.Vector ItemsList =3D null ;=09 private String SelectedItem =3D null ; =09 private Node RootNode =3D null ; private Node ViewRootNode =3D null ; =09 private void setSelectedItem (String selectedItem) { this.SelectedItem =3D selectedItem ; } private void setDefaultTree (Vector itemsList, String selectedItem) { this.ItemsList =3D itemsList ; this.SelectedItem =3D selectedItem ; =09 } private String getSelectedItem () { return (this.SelectedItem) ; } private Vector getItemsList () { return (this.ItemsList) ; } //testing phase! - lots of temporary inclusions... private void setDisplay () { this.setupConfig () ; System.out.println ("Generated the criteria elements list") ; CriteriaViewerInstance =3D new CriteriaViewer (this.getItemsList (), this.getSelectedItem (), this) ; System.out.println ("generated the criteria viewer") ; =09 this.parseXML () ; =09 this.cloneTree () ; // generate TreeViewer instance this.generateTreeViewer () ; System.out.println ("generated the tree viewer (default)") ; // build the outermost GUI components LogSplitPane =3D new JSplitPane (JSplitPane.HORIZONTAL_SPLIT) ; LogSplitPane.setOneTouchExpandable(true); =09 LogSplitPane.setLeftComponent (CriteriaViewerInstance) ; LogSplitPane.setRightComponent (TreeViewerInstance) ; // Set the initial location and size of the divider LogSplitPane.setDividerLocation(150); LogSplitPane.setDividerSize(10); // Provide a preferred size for the split pane LogSplitPane.setPreferredSize(new Dimension(400, 200)); =09 =09 this.getContentPane ().add ("Center", LogSplitPane) ; System.out.println ("laid out all the display components") ; } =09 private void setupConfig () { try { //String browserConfigValue =3D this.getParameter ("browserConfig") = ; String browserConfigValue =3D new String = ("http://raghu/browser.cfg") ; System.out.println ("Config URL =3D " + browserConfigValue) ; URL url =3D new URL (browserConfigValue) ; URLConnection browserURLConnection =3D url.openConnection () ; InputStream inputStream =3D browserURLConnection.getInputStream () ; System.out.println ("Got reference to the inputstream") ; =09 ConfigParserInstance =3D new ConfigParser (inputStream) ; ConfigParserInstance.parse () ; Vector criteriaElementsList =3D=20 ConfigParserInstance.getCriteriaElementsList () ; this.setDefaultTree (criteriaElementsList,=20 (String)criteriaElementsList.firstElement ()) ;=20 }=20 catch (java.lang.Exception e) { e.printStackTrace () ; } =09 =09 } =09 private void parseXML () { try { // parse the XML file and generate a tree URL url =3D new URL (ConfigParserInstance.getBillingLogURL ()) ; URLConnection browserURLConnection =3D url.openConnection () ; InputStream inputStream =3D browserURLConnection.getInputStream () = ; XMLParser parser =3D new XMLParser (inputStream) ; parser.parse () ; System.out.println ("parsed the XML data") ; RootNode =3D parser.getRootNode () ; =09 }=20 catch (java.lang.Exception e) { e.printStackTrace () ; } =09 } =09 private void generateTreeViewer () { System.out.println ("About to generate a tree viewer ...") ; // produce tree based on the default view TreeConverterInstance =3D new TreeConverter (ViewRootNode) ; System.out.println ("Before Conversion :Children Size =3D " +=20 (RootNode.getChildren ()).size ()) ; TreeConverterInstance.convert (this.getSelectedItem ()) ; System.out.println ("generated a converted tree based " +=20 "on the selected element") ;=09 System.out.println ("After Conversion :Children Size =3D " +=20 (RootNode.getChildren ()).size ()) ; // create the JTree (Swing component) using the converted tree LogTree logTree =3D new LogTree (ViewRootNode) ; System.out.println ("generated the log tree ") ; // build the tree viewer TreeViewerInstance =3D new TreeViewer (logTree) ; System.out.println ("completed generation of the " +=20 " tree viewer!") ; }=09 =09 private void cloneTree () { //throws java.lang.CloneNotSupportedException { System.out.println ("LogBrowserApplet: Children Size =3D " +=20 (RootNode.getChildren ()).size ()) ; ViewRootNode =3D null ; ViewRootNode =3D RootNode.cloneNode () ; System.out.println ("Completed generation of a clone of the original = tree") ; } private void setTreeViewerPane () { LogSplitPane.setRightComponent (TreeViewerInstance) ; LogSplitPane.revalidate () ; } } // end class ------=_NextPart_000_0080_01BDCD00.FB02CA00 Content-Type: application/octet-stream; name="Node.java" Content-Transfer-Encoding: quoted-printable Content-Disposition: attachment; filename="Node.java" /**=09 * Node.java */ package com.deluxe.deps.billing.log.browser ; import java.util.Vector ; import java.util.Enumeration ; import com.sun.java.swing.tree.TreeNode ; import com.sun.java.swing.tree.MutableTreeNode ; /** * The Node class represents a node of * tree. It contains node-related information. They are * name & value (stored in n object of =20 * NodeInformation class), pointer to 'parent' node, * and a list of its children. *

* It implements the com.sun.java.swing.tree.MutableTreeNode * interface. This enables usage of objects of * Node class to be used in a com.sun.java.swing.JTree=20 * object for tree generation and rendering. *

* It also consists of utility methods for 'cloning' a node. * * @author Raghu Havaldar - STR * @see com.sun.java.swing.JTree * @see com.sun.java.swing.tree.TreeNode * @see com.sun.java.swing.tree.MutableTreeNode * @see java.util.Vector * @see com.deluxe.deps.billing.log.browser.NodeInformation * @since JDK 1.2 Beta 4 */ public class Node=20 implements com.sun.java.swing.tree.MutableTreeNode { /** * This constructor sets default values for its members. * The value of its parent is not set. * * @see com.deluxe.deps.billing.log.browser.NodeInformation * @see java.util.Vector * @since JDK 1.2 Beta 4 */=09 public Node () { this.NodeInfo =3D new NodeInformation () ; this.Children =3D new Vector () ; } /** * This constructor sets values for its members including the * value of its parent. * * @param nodeInfo information regarding the node - name and value * @param parent the parent of this node * @see com.deluxe.deps.billing.log.browser.NodeInformation * @see java.util.Vector * @since JDK 1.2 Beta 4 */=09 public Node (NodeInformation nodeInfo, TreeNode parent) { this () ; this.NodeInfo =3D nodeInfo ; this.ParentNode =3D (Node)parent ; } // set methods /** * sets the name of the node * * @param name name of the node * @see com.deluxe.deps.billing.log.browser.NodeInformation * @since JDK 1.2 Beta 4 */=09 public void setName (String name) { (this.NodeInfo).setName (name) ; } /** * sets the value of the node * * @param value value of the node * @see com.deluxe.deps.billing.log.browser.NodeInformation * @since JDK 1.2 Beta 4 */=09 public void setValue (String value) { (this.NodeInfo).setValue (value) ; } /** * sets the parent of the node * * @param parentNode parent of the node * @see com.deluxe.deps.billing.log.browser.NodeInformation * @since JDK 1.2 Beta 4 */=09 public void setParentNode (TreeNode parentNode) { this.ParentNode =3D (Node)parentNode ; } /** * adds a child to the node * * @param child node which would be added as a child * @since JDK 1.2 Beta 4 */=09 public void addChildNode (TreeNode child) { (this.Children).addElement (child) ; } /** * sets the children of the node * * @param children the new children of the node * @see java.util.Vector * @since JDK 1.2 Beta 4 */ =09 public void setChildren (Vector children) { this.Children =3D children ; } // accessor methods /** * get the name of the node * * @return the name of the node * @see com.deluxe.deps.billing.log.browser.NodeInformation * @since JDK 1.2 Beta 4 */=09 public String getName () { return ((this.NodeInfo).getName ()) ; } /** * get the value of the node * * @return the value of the node * @see com.deluxe.deps.billing.log.browser.NodeInformation * @since JDK 1.2 Beta 4 */=09 public String getValue () { return ((this.NodeInfo).getValue()) ; } /** * get the parent of the node * * @return the parent node * @since JDK 1.2 Beta 4 */=09 public Node getParentNode () { return (this.ParentNode) ; } /** * get all the children of the node * * @return the children of the node * @since JDK 1.2 Beta 4 */ =09 public Vector getChildren () { return (this.Children) ; } /** * get the number of children of the node * * @return the number of children of the node * @since JDK 1.2 Beta 4 */ =09 public int getChildrenSize () { return ((this.getChildren ()).size ()) ; } // utility methods /** * checks if the a child exists with the identified 'name' * * @param name of the 'expected' child * @return true if a child exists with the name,=20 * false if not. * @see com.deluxe.deps.billing.log.browser.NodeInformation * @since JDK 1.2 Beta 4 */=09 public boolean isChild (String name) { boolean flag =3D false ; =09 for (int i=3D0; i com.deluxe.deps.billing.log.browser.Renderer * class for appropriate rendering based on the type of node. * * @return the string representation of the node * @see com.deluxe.deps.billing.log.browser.Renderer * @since JDK 1.2 Beta 4 */ public String toString () { return (Renderer.render (this.getName (), this.getValue ())) ; =09 } /** * makes a deep copy and returns a 'new' node. This new * node is an exact clone of this node. * * @return the node with the specified name * @since JDK 1.2 Beta 4 */ public Node cloneNode () { =09 Node nodeCopy =3D new Node () ;=20 this.generateCopy (this, nodeCopy) ; return (nodeCopy) ;=09 } // methods specific to the com.sun.java.swing.TreeNode interface =09 /** * returns the children of the node as an Enumeration * * @return the children of the node * @since JDK 1.2 Beta 4 */=20 public Enumeration children () { return ((this.getChildren ()).elements ()) ; } /** * returns true if the node allows children. * * @return true if the node allows * children, false otherwise. * @since JDK 1.2 Beta 4 */ public boolean getAllowsChildren() { return (true) ; // default mechanism } // Returns the child TreeNode at index childIndex.=20 /** * get the child node at a particular index * * @param childName name of the child * @return the node with the specified name * @see com.deluxe.deps.billing.log.browser.NodeInformation * @since JDK 1.2 Beta 4 */ =20 public TreeNode getChildAt (int childIndex) { Vector children =3D this.getChildren () ; return ((TreeNode)children.elementAt (childIndex)) ; =20 } /** * returns the number of children the node contains. * * @return the number of children * @since JDK 1.2 Beta 4 */ public int getChildCount () { return ((this.getChildren ()).size ()) ; } =20 /** * returns the index of child node in the node's children * * @return the index of the child node * @since JDK 1.2 Beta 4 */ public int getIndex (TreeNode node) { int index =3D -1 ; =09 if ((this.getChildren ()).contains (node)) index =3D (this.getChildren ()).indexOf (node) ; return (index) ; } =20 /** * returns the parent of the node. * * @return the parent of the node * @since JDK 1.2 Beta 4 */ public TreeNode getParent () { return ((TreeNode)this.getParentNode ()) ; } /** * checks if the node is a leaf.=20 * * @return true if it is a leaf,=20 * false otherwise. * @since JDK 1.2 Beta 4 */ =20 public boolean isLeaf () { boolean flag =3D false ; if ((this.getChildren () =3D=3D null) || ((this.getChildren ()).isEmpty ())) flag =3D true ; return (flag) ; } =20 /* methods specific to the com.sun.java.swing.tree.MutableTreeNode * interface */=20 /** * adds child to the receiver at index. * * @param child the node to be added as child * @param index the position where the node has to be added * @since JDK 1.2 Beta 4 */ public void insert (MutableTreeNode child, int index) { (this.getChildren ()).insertElementAt (child, index) ; } =20 /** * removes the child at index from the receiver. * * @param index the position from which a=20 * child node has to be removed * @since JDK 1.2 Beta 4 */ public void remove (int index) { (this.getChildren ()).remove (index) ; } =20 /** * removes the specified child from the node * * @param node the specified child node * @since JDK 1.2 Beta 4 */ public void remove (MutableTreeNode node) { (this.getChildren ()).remove (node) ; } =20 /** * removes the node from its parent. Implictly=20 * removes the pointer to its parent node. * * @since JDK 1.2 Beta 4 */ public void removeFromParent () { this.setParentNode (null) ; } =20 /** * sets the new parent of the node * * @param newParent the new parent * @since JDK 1.2 Beta 4 */ public void setParent(MutableTreeNode newParent) { this.setParentNode (newParent) ; } =20 /** * resets the user object of the node. This user object * represents an object which can be associated with a node * a tree (for application-specific purposes). * * @param object the user object to be associated with the node * @since JDK 1.2 Beta 4 */ public void setUserObject (Object object) { this.NodeInfo =3D (NodeInformation)object ; } // private members private NodeInformation NodeInfo =3D null ; private Node ParentNode =3D null ; private Vector Children =3D null ; private void generateCopy (Node referenceNode, Node copyNode) { if (referenceNode.getParentNode () =3D=3D null) { // generating the root String copyRootName =3D new String (referenceNode.getName ()) ; copyNode.setName (copyRootName) ; String copyRootValue =3D new String (referenceNode.getValue ()) ;=09 copyNode.setValue (copyRootValue) ;=09 // no parent for root =09 copyNode.setParentNode (referenceNode.getParentNode ()) ; =09 }// end if =09 Vector referenceNodeChildren =3D referenceNode.getChildren () ; for (int i=3D0; i TreeConverter converts the structure of=20 * a tree from one form to another based on the 'view' selected=20 * by the user.=20 *

* This conversion is custom-specific and as per the * requirements. It could however be modified easily as=20 * the requirements change. * * @author Raghu Havaldar - STR * @see java.io.InputStream * @see java.util.List * @see java.util.Collections * @see java.util.Vector * @see java.util.Comparator * @see com.deluxe.deps.billing.log.browser.Node * @see com.deluxe.deps.billing.log.browser.DateComparator * @see com.deluxe.deps.billing.log.browser.StringComparator * @see com.deluxe.deps.billing.log.browser.TimeComparator * @since JDK 1.2 Beta 4 */ public class TreeConverter { /** * A constructor which accepts the = com.deluxe.deps.billing.log.browser.Node=20 * as an argument. This node represents the root node of the = tree which needs * to be converted from one form to another based on a 'view'. * * @param rootNode the node which represents the root of the original = tree. * @see com.deluxe.deps.billing.log.browser.Node * @since JDK 1.2 Beta 4 */ public TreeConverter (Node rootNode) { this.RootNode =3D rootNode ; } /** * It converts the tree from one form to another based on the = 'view'. * This view is specified as the input. * * @param criteriaElement represents the view critieria. * @see java.util.List * @see java.util.Collections * @see java.util.Vector * @see com.deluxe.deps.billing.log.browser.Node * @see com.deluxe.deps.billing.log.browser.DateComparator * @see com.deluxe.deps.billing.log.browser.StringComparator * @see com.deluxe.deps.billing.log.browser.TimeComparator * @since JDK 1.2 Beta 4 */ public void convert (String criteriaElement) { // the node to handle 'unknown' or non-parseable entries Node unknownNode =3D new Node () ; unknownNode.setName ("Unknown List") ; unknownNode.setValue ("") ; =20 // Stage 1 // get the children of the 'root' node Vector children =3D (this.getRootNode ()).getChildren () ; // make a copy of the children nodes Vector childrenCopy =3D (Vector)children.clone () ; // and, remove them from the 'root' node (this.getRootNode ()).removeAllChildren () ; for (int i=3D0; i 0) { // swap elements list.set (i, element2) ; list.set (j, element1) ; } // end if } // end for j } // end for i } } // end class TreeConverter ------=_NextPart_000_0080_01BDCD00.FB02CA00--