From 428cd54a81fe07ad38a9997303ac90d3dfd0b6b7 Mon Sep 17 00:00:00 2001 From: Alarik Myrin Date: Sat, 9 Aug 2014 13:59:20 -0400 Subject: [PATCH] KEYCLOAK-621 fix searchForUserByAttributes method so that it works and is not subject to SQL injection --- .../keycloak/models/jpa/JpaUserProvider.java | 45 +++++++++++++------ 1 file changed, 32 insertions(+), 13 deletions(-) diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/JpaUserProvider.java b/model/jpa/src/main/java/org/keycloak/models/jpa/JpaUserProvider.java index 326c3aa3fb..ca35cf345e 100755 --- a/model/jpa/src/main/java/org/keycloak/models/jpa/JpaUserProvider.java +++ b/model/jpa/src/main/java/org/keycloak/models/jpa/JpaUserProvider.java @@ -26,6 +26,12 @@ import java.util.Set; * @version $Revision: 1 $ */ public class JpaUserProvider implements UserProvider { + + private static final String EMAIL = "email"; + private static final String USERNAME = "username"; + private static final String FIRST_NAME = "firstName"; + private static final String LAST_NAME = "lastName"; + private final KeycloakSession session; protected EntityManager em; @@ -240,32 +246,45 @@ public class JpaUserProvider implements UserProvider { @Override public List searchForUserByAttributes(Map attributes, RealmModel realm, int firstResult, int maxResults) { - StringBuilder builder = new StringBuilder("select u from UserEntity u"); - boolean first = true; + StringBuilder builder = new StringBuilder("select u from UserEntity u where u.realmId = :realmId"); for (Map.Entry entry : attributes.entrySet()) { String attribute = null; + String parameterName = null; if (entry.getKey().equals(UserModel.USERNAME)) { - attribute = "lower(username)"; + attribute = "lower(u.username)"; + parameterName = JpaUserProvider.USERNAME; } else if (entry.getKey().equalsIgnoreCase(UserModel.FIRST_NAME)) { - attribute = "lower(firstName)"; + attribute = "lower(u.firstName)"; + parameterName = JpaUserProvider.FIRST_NAME; } else if (entry.getKey().equalsIgnoreCase(UserModel.LAST_NAME)) { - attribute = "lower(lastName)"; + attribute = "lower(u.lastName)"; + parameterName = JpaUserProvider.LAST_NAME; } else if (entry.getKey().equalsIgnoreCase(UserModel.EMAIL)) { - attribute = "lower(email)"; + attribute = "lower(u.email)"; + parameterName = JpaUserProvider.EMAIL; } if (attribute == null) continue; - if (first) { - first = false; - builder.append(" where realm = :realm"); - } else { - builder.append(" and "); - } - builder.append(attribute).append(" like '%").append(entry.getValue().toLowerCase()).append("%'"); + builder.append(" and "); + builder.append(attribute).append(" like :").append(parameterName); } builder.append(" order by u.username"); String q = builder.toString(); TypedQuery query = em.createQuery(q, UserEntity.class); query.setParameter("realmId", realm.getId()); + for (Map.Entry entry : attributes.entrySet()) { + String parameterName = null; + if (entry.getKey().equals(UserModel.USERNAME)) { + parameterName = JpaUserProvider.USERNAME; + } else if (entry.getKey().equalsIgnoreCase(UserModel.FIRST_NAME)) { + parameterName = JpaUserProvider.FIRST_NAME; + } else if (entry.getKey().equalsIgnoreCase(UserModel.LAST_NAME)) { + parameterName = JpaUserProvider.LAST_NAME; + } else if (entry.getKey().equalsIgnoreCase(UserModel.EMAIL)) { + parameterName = JpaUserProvider.EMAIL; + } + if (parameterName == null) continue; + query.setParameter(parameterName, "%" + entry.getValue().toLowerCase() + "%"); + } if (firstResult != -1) { query.setFirstResult(firstResult); }