Author: syoung
Date: 2006-04-11 03:22:38 +0000 (Tue, 11 Apr 2006)
New Revision: 8506

Modified:
   trunk/freenet/src/freenet/clients/http/DarknetConnectionsToadlet.java
   trunk/freenet/src/freenet/node/Version.java
Log:
Close a potential security hole by properly encoding HTML entities in the node 
version number (to over-simplify, think of a node that uses a version of "<form 
action="http://example.com/malicious.cgi";>CHK: <input></form>").
Immediately close the connection after reading the node reference from a URL.
Node reference filename field was not being trimmed of whitespace.

Modified: trunk/freenet/src/freenet/clients/http/DarknetConnectionsToadlet.java
===================================================================
--- trunk/freenet/src/freenet/clients/http/DarknetConnectionsToadlet.java       
2006-04-10 23:00:04 UTC (rev 8505)
+++ trunk/freenet/src/freenet/clients/http/DarknetConnectionsToadlet.java       
2006-04-11 03:22:38 UTC (rev 8506)
@@ -39,7 +39,7 @@

        }

-       Node node;
+       private Node node;

        protected DarknetConnectionsToadlet(Node n, HighLevelSimpleClient 
client) {
                super(client);
@@ -61,9 +61,10 @@
                        return;
                }

-               StringBuffer buf = new StringBuffer();
+               StringBuffer buf = new StringBuffer(1024);

-               HTTPRequest request = new HTTPRequest(uri);
+               //HTTPRequest request = new HTTPRequest(uri);
+
                ctx.getPageMaker().makeHead(buf, "Darknet Connections");

                // our reference
@@ -99,6 +100,7 @@
                        int backoff = (int)(Math.max(backedOffUntil - now, 0));
                        long idle = pn.lastReceivedPacketTime();

+                       // Elements must be HTML encoded.
                        Object[] row = new Object[8];
                        rows[i] = row;

@@ -116,13 +118,13 @@

                        row[0] = status;
                        row[1] = HTMLEncoder.encode(pn.getName());
-                       row[2] = pn.getDetectedPeer() != null ? 
pn.getDetectedPeer().toString() : "(address unknown)";
-                       row[3] = pn.getVersion();
+                       row[2] = pn.getDetectedPeer() != null ? 
HTMLEncoder.encode(pn.getDetectedPeer().toString()) : "(address unknown)";
+                       row[3] = HTMLEncoder.encode(pn.getVersion());
                        row[4] = new Double(pn.getLocation().getValue());
-                       row[5] = new String(backoff + "/" + 
pn.getBackoffLength());
+                       row[5] = backoff + "/" + pn.getBackoffLength();
                        if (idle == -1) row[6] = " ";
                        else row[6] = new Long((now - idle) / 60000);
-                       row[7] = new String("<input type=\"checkbox\" 
name=\"delete_node_"+pn.hashCode()+"\" />");
+                       row[7] = "<input type=\"checkbox\" 
name=\"delete_node_"+pn.hashCode()+"\" />";
                }

                // Sort array
@@ -141,13 +143,13 @@
                // Turn array into HTML
                for(int i=0;i<rows.length;i++) {
                        Object[] row = rows[i];
-                       buf.append("<tr><td>");
+                       buf.append("\n<tr>\n\t<td>");
                        for(int j=0;j<row.length;j++) {
                                buf.append(row[j]);
                                if(j != row.length-1)
-                                       buf.append("</td><td>");
+                                       buf.append("</td>\n\t<td>");
                        }
-                       buf.append("</td></tr>");
+                       buf.append("</td>\n</tr>\n");
                }
                buf.append("</table>");
                buf.append("<input type=\"submit\" name =\"disconnect\" 
value=\"Disconnect from Selected Peers\" />");
@@ -183,9 +185,9 @@
                        this.writeReply(ctx, 400, "text/plain", "Too big", "Too 
much data, darknet toadlet limited to 1MB");
                        return;
                }
-               HTTPRequest request;
-               request = new HTTPRequest(uri, data, ctx);

+               HTTPRequest request = new HTTPRequest(uri, data, ctx);
+               
                if (request.isPartSet("connect")) {
                        // connect to a new node
                        String urltext = request.getPartAsString("url", 100);
@@ -194,38 +196,39 @@
                        reftext = reftext.trim();
                        if (reftext.length() < 200) {
                                reftext = request.getPartAsString("reffile", 
2000);
+                               reftext = reftext.trim();
                        }
-                       reftext.trim();

-                       String ref = new String("");
-                       
+                       String ref = "";
                        if (urltext.length() > 0) {
                                // fetch reference from a URL
+                               BufferedReader in = null;
                                try {
                                        URL url = new URL(urltext);
                                        URLConnection uc = url.openConnection();
-                                       BufferedReader in = new BufferedReader(
-                                                       new 
InputStreamReader(uc.getInputStream()));
+                                       in = new BufferedReader(new 
InputStreamReader(uc.getInputStream()));
                                        String line;
                                        while ( (line = in.readLine()) != null) 
{
                                                ref += line+"\n";
                                        }
-                               } catch (Exception e) {
+                               } catch (IOException e) {
                                        this.sendErrorPage(ctx, 200, "OK", 
"Failed to add node: Unable to retrieve node reference from "+urltext+".");
+                               } finally {
+                                       if( in != null ){
+                                               in.close();
+                                       }
                                }
                        } else if (reftext.length() > 0) {
                                // read from post data or file upload
                                // this slightly scary looking regexp chops any 
extra characters off the beginning or ends of lines and removes extra line 
breaks
                                ref = 
reftext.replaceAll(".*?((?:[\\w,\\.]+\\=[^\r\n]+)|(?:End)).*(?:\\r?\\n)*", 
"$1\n");
-                               if (ref.endsWith("\n")) {
-                                       ref = ref.substring(0, ref.length() - 
1);
-                               }
                        } else {
                                this.sendErrorPage(ctx, 200, "OK", "Failed to 
add node: Could not detect either a node reference or a URL. Please <a 
href=\".\">Try again</a>.");
                                request.freeParts();
                                return;
                        }
-                       
+                       ref = ref.trim();
+
                        request.freeParts();
                        // we have a node reference in ref
                        SimpleFieldSet fs;
@@ -262,4 +265,5 @@
                }
                this.handleGet(uri, ctx);
        }
+
 }

Modified: trunk/freenet/src/freenet/node/Version.java
===================================================================
--- trunk/freenet/src/freenet/node/Version.java 2006-04-10 23:00:04 UTC (rev 
8505)
+++ trunk/freenet/src/freenet/node/Version.java 2006-04-11 03:22:38 UTC (rev 
8506)
@@ -20,7 +20,7 @@
        public static final String protocolVersion = "1.0";

        /** The build number of the current revision */
-       private static final int buildNumber = 626;
+       private static final int buildNumber = 627;

        /** Oldest build of Fred we will talk to */
        private static final int lastGoodBuild = 591;


Reply via email to