From 4ac439101d8a60be50af5766da392dcd638e351e Mon Sep 17 00:00:00 2001
From: Endi Sukma Dewata <edewata@redhat.com>
Date: Wed, 14 Mar 2012 12:51:23 -0500
Subject: [PATCH] Escape parameter values in search filter.

The REST interface was vulnerable to injection attack. This has
been fixed by escaping the special characters in parameter values
before using them in the search filter.

Ticket #96
---
 .../cms/servlet/key/KeysResourceService.java       |    5 ++-
 .../request/KeyRequestsResourceService.java        |    7 +++--
 .../src/com/netscape/cmsutil/ldap/LDAPUtil.java    |   23 ++++++++++++++++++++
 3 files changed, 30 insertions(+), 5 deletions(-)

diff --git a/pki/base/common/src/com/netscape/cms/servlet/key/KeysResourceService.java b/pki/base/common/src/com/netscape/cms/servlet/key/KeysResourceService.java
index b5032fa86c93c2b0fd5053df38f9f7b255748ed6..a7876a6c68418a837193089d527cddf43df89cb9 100644
--- a/pki/base/common/src/com/netscape/cms/servlet/key/KeysResourceService.java
+++ b/pki/base/common/src/com/netscape/cms/servlet/key/KeysResourceService.java
@@ -30,6 +30,7 @@ import com.netscape.certsrv.base.EBaseException;
 import com.netscape.cms.servlet.base.CMSResourceService;
 import com.netscape.cms.servlet.key.model.KeyDAO;
 import com.netscape.cms.servlet.key.model.KeyDataInfos;
+import com.netscape.cmsutil.ldap.LDAPUtil;
 
 /**
  * @author alee
@@ -71,12 +72,12 @@ public class KeysResourceService extends CMSResourceService implements KeysResou
         }
         
         if (status != null) {
-            filter += "(status=" + status + ")";
+            filter += "(status=" + LDAPUtil.escape(status) + ")";
             matches ++;
         }
         
         if (clientID != null) {
-            filter += "(clientID=" + clientID + ")";
+            filter += "(clientID=" + LDAPUtil.escape(clientID) + ")";
             matches ++;
         }
         
diff --git a/pki/base/common/src/com/netscape/cms/servlet/request/KeyRequestsResourceService.java b/pki/base/common/src/com/netscape/cms/servlet/request/KeyRequestsResourceService.java
index 9b11a96d606f248de483d4d5b319ec196ef66460..11898ef7a2d7e79e4cfdc4b0018b3e4b9d2ebf46 100644
--- a/pki/base/common/src/com/netscape/cms/servlet/request/KeyRequestsResourceService.java
+++ b/pki/base/common/src/com/netscape/cms/servlet/request/KeyRequestsResourceService.java
@@ -29,6 +29,7 @@ import com.netscape.certsrv.request.RequestId;
 import com.netscape.cms.servlet.base.CMSResourceService;
 import com.netscape.cms.servlet.request.model.KeyRequestDAO;
 import com.netscape.cms.servlet.request.model.KeyRequestInfos;
+import com.netscape.cmsutil.ldap.LDAPUtil;
 
 /**
  * @author alee
@@ -77,17 +78,17 @@ public class KeyRequestsResourceService extends CMSResourceService implements Ke
         }
         
         if (requestState != null) {
-            filter += "(requeststate=" + requestState + ")";
+            filter += "(requeststate=" + LDAPUtil.escape(requestState) + ")";
             matches ++;
         }
         
         if (requestType != null) {
-            filter += "(requesttype=" + requestType + ")";
+            filter += "(requesttype=" + LDAPUtil.escape(requestType) + ")";
             matches ++;
         }
         
         if (clientID != null) {
-            filter += "(clientID=" + clientID + ")";
+            filter += "(clientID=" + LDAPUtil.escape(clientID) + ")";
             matches ++;
         }
         
diff --git a/pki/base/util/src/com/netscape/cmsutil/ldap/LDAPUtil.java b/pki/base/util/src/com/netscape/cmsutil/ldap/LDAPUtil.java
index a78f8ac552bd1556d4b46f0202306007e72f502e..822bda1230c0a19012e95fb7e2f6dba74272c2ac 100644
--- a/pki/base/util/src/com/netscape/cmsutil/ldap/LDAPUtil.java
+++ b/pki/base/util/src/com/netscape/cmsutil/ldap/LDAPUtil.java
@@ -33,6 +33,29 @@ import netscape.ldap.util.LDIFModifyContent;
 import netscape.ldap.util.LDIFRecord;
 
 public class LDAPUtil {
+
+    public static String SPECIAL_FILTER_CHARS = "*()\\\000";
+
+    /**
+     * This method escapes special characters for LDAP filter (RFC 4515).
+     *
+     * @param string string to escape
+     * @return escaped string
+     */
+    public static String escape(String string) {
+        StringBuilder sb = new StringBuilder();
+        for (char c : string.toCharArray()) {
+            if (SPECIAL_FILTER_CHARS.indexOf(c) >= 0) {
+                sb.append('\\');
+                if (c < 0x10) sb.append('0');
+                sb.append(Integer.toHexString(c));
+            } else {
+                sb.append(c);
+            }
+        }
+        return sb.toString();
+    }
+
     public static void importLDIF(LDAPConnection conn, String filename, ArrayList<String> errors) throws IOException {
         LDIF ldif = new LDIF(filename);
         while (true) {
-- 
1.7.7.4

