FELIX-3010 : XSS in Felix Web Console

git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@1147461 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/webconsole/src/main/java/org/apache/felix/webconsole/internal/compendium/ConfigManager.java b/webconsole/src/main/java/org/apache/felix/webconsole/internal/compendium/ConfigManager.java
index 4d7fb9e..9ac756d 100644
--- a/webconsole/src/main/java/org/apache/felix/webconsole/internal/compendium/ConfigManager.java
+++ b/webconsole/src/main/java/org/apache/felix/webconsole/internal/compendium/ConfigManager.java
@@ -17,23 +17,10 @@
 package org.apache.felix.webconsole.internal.compendium;
 
 
-import java.io.ByteArrayInputStream;
-import java.io.IOException;
-import java.io.PrintWriter;
+import java.io.*;
 import java.lang.reflect.Array;
-import java.util.Arrays;
-import java.util.Dictionary;
-import java.util.Enumeration;
-import java.util.Hashtable;
-import java.util.Iterator;
-import java.util.Locale;
-import java.util.Map;
+import java.util.*;
 import java.util.Map.Entry;
-import java.util.Properties;
-import java.util.SortedMap;
-import java.util.StringTokenizer;
-import java.util.TreeMap;
-import java.util.Vector;
 
 import javax.servlet.ServletException;
 import javax.servlet.http.HttpServletRequest;
@@ -42,20 +29,9 @@
 import org.apache.felix.webconsole.DefaultVariableResolver;
 import org.apache.felix.webconsole.WebConsoleUtil;
 import org.apache.felix.webconsole.internal.Util;
-import org.json.JSONArray;
-import org.json.JSONException;
-import org.json.JSONObject;
-import org.json.JSONWriter;
-import org.osgi.framework.Bundle;
-import org.osgi.framework.Constants;
-import org.osgi.framework.Filter;
-import org.osgi.framework.InvalidSyntaxException;
-import org.osgi.framework.ServiceReference;
-import org.osgi.framework.Version;
-import org.osgi.service.cm.Configuration;
-import org.osgi.service.cm.ConfigurationAdmin;
-import org.osgi.service.cm.ManagedService;
-import org.osgi.service.cm.ManagedServiceFactory;
+import org.json.*;
+import org.osgi.framework.*;
+import org.osgi.service.cm.*;
 import org.osgi.service.metatype.AttributeDefinition;
 import org.osgi.service.metatype.ObjectClassDefinition;
 
@@ -87,6 +63,19 @@
         TEMPLATE = readTemplateFile( "/templates/config.html" );
     }
 
+    private boolean isAllowedPid(final String pid)
+    {
+        for(int i = 0; i < pid.length(); i++)
+        {
+            final char c = pid.charAt(i);
+            if ( c == '&' || c == '<' || c == '>' || c == '"' || c == '\'' )
+            {
+                return false;
+            }
+        }
+        return true;
+    }
+
     /**
      * @see javax.servlet.http.HttpServlet#doPost(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
      */
@@ -112,6 +101,18 @@
             return;
         }
 
+        // ignore this request, if the pid is invalud
+        if ( ! isAllowedPid(pid) )
+        {
+            response.sendError(500);
+            return;
+        }
+        if ( pidFilter != null && ! isAllowedPid(pidFilter) )
+        {
+            response.sendError(500);
+            return;
+        }
+
         // the configuration to operate on (to be created or "missing")
         Configuration config = null;
 
@@ -218,6 +219,16 @@
                 pidFilter = null;
             }
 
+            // check both pid and pid filter
+            if ( pid != null && !this.isAllowedPid(pid) )
+            {
+                response.sendError(500);
+            }
+            if ( pidFilter != null && !this.isAllowedPid(pidFilter) )
+            {
+                response.sendError(500);
+            }
+
             final ConfigurationAdmin ca = this.getConfigurationAdmin();
 
             final Locale loc = getLocale( request );
@@ -294,6 +305,15 @@
             }
         }
 
+        // check both pid and pid filter
+        if ( pid != null && !this.isAllowedPid(pid) )
+        {
+            response.sendError(500);
+        }
+        if ( pidFilter != null && !this.isAllowedPid(pidFilter) )
+        {
+            response.sendError(500);
+        }
         final ConfigurationAdmin ca = this.getConfigurationAdmin();
 
         final Locale loc = getLocale( request );
@@ -403,8 +423,9 @@
             {
 
                 // ignore configuration object if an entry already exists in the map
-                String pid = cfgs[i].getPid();
-                if (optionsPlain.containsKey(pid))
+                // or if it is invalid
+                final String pid = cfgs[i].getPid();
+                if (optionsPlain.containsKey(pid) || !this.isAllowedPid(pid) )
                 {
                     continue;
                 }
@@ -494,7 +515,8 @@
         for ( int i = 0; refs != null && i < refs.length; i++ )
         {
             Object pidObject = refs[i].getProperty( Constants.SERVICE_PID );
-            if ( pidObject instanceof String )
+            // only include valid pids
+            if ( pidObject instanceof String && this.isAllowedPid((String)pidObject) )
             {
                 String pid = ( String ) pidObject;
                 String name;