VYPR
Medium severity6.5NVD Advisory· Published Jun 13, 2017· Updated May 13, 2026

CVE-2017-4974

CVE-2017-4974

Description

An issue was discovered in Cloud Foundry Foundation cf-release versions prior to v258; UAA release 2.x versions prior to v2.7.4.15, 3.6.x versions prior to v3.6.9, 3.9.x versions prior to v3.9.11, and other versions prior to v3.16.0; and UAA bosh release (uaa-release) 13.x versions prior to v13.13, 24.x versions prior to v24.8, and other versions prior to v30.1. An authorized user can use a blind SQL injection attack to query the contents of the UAA database, aka "Blind SQL Injection with privileged UAA endpoints."

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
org.cloudfoundry.identity:cloudfoundry-identity-serverMaven
>= 2.0.0, < 2.7.4.152.7.4.15
org.cloudfoundry.identity:cloudfoundry-identity-serverMaven
>= 3.0.0, < 3.6.93.6.9
org.cloudfoundry.identity:cloudfoundry-identity-serverMaven
>= 3.7.0, < 3.9.113.9.11
org.cloudfoundry.identity:cloudfoundry-identity-serverMaven
>= 3.10.0, < 3.16.03.16.0

Affected products

65
  • cpe:2.3:a:cloudfoundry:cf-release:*:*:*:*:*:*:*:*
    Range: <=v257
  • cpe:2.3:a:cloudfoundry:cloud_foundry_uaa_bosh:*:*:*:*:*:*:*:*+ 23 more
    • cpe:2.3:a:cloudfoundry:cloud_foundry_uaa_bosh:*:*:*:*:*:*:*:*range: <=30
    • cpe:2.3:a:cloudfoundry:cloud_foundry_uaa_bosh:13.1:*:*:*:*:*:*:*
    • cpe:2.3:a:cloudfoundry:cloud_foundry_uaa_bosh:13.10:*:*:*:*:*:*:*
    • cpe:2.3:a:cloudfoundry:cloud_foundry_uaa_bosh:13.11:*:*:*:*:*:*:*
    • cpe:2.3:a:cloudfoundry:cloud_foundry_uaa_bosh:13.12:*:*:*:*:*:*:*
    • cpe:2.3:a:cloudfoundry:cloud_foundry_uaa_bosh:13.2:*:*:*:*:*:*:*
    • cpe:2.3:a:cloudfoundry:cloud_foundry_uaa_bosh:13.3:*:*:*:*:*:*:*
    • cpe:2.3:a:cloudfoundry:cloud_foundry_uaa_bosh:13.4:*:*:*:*:*:*:*
    • cpe:2.3:a:cloudfoundry:cloud_foundry_uaa_bosh:13.5:*:*:*:*:*:*:*
    • cpe:2.3:a:cloudfoundry:cloud_foundry_uaa_bosh:13.6:*:*:*:*:*:*:*
    • cpe:2.3:a:cloudfoundry:cloud_foundry_uaa_bosh:13.7:*:*:*:*:*:*:*
    • cpe:2.3:a:cloudfoundry:cloud_foundry_uaa_bosh:13.8:*:*:*:*:*:*:*
    • cpe:2.3:a:cloudfoundry:cloud_foundry_uaa_bosh:13.9:*:*:*:*:*:*:*
    • cpe:2.3:a:cloudfoundry:cloud_foundry_uaa_bosh:24:*:*:*:*:*:*:*
    • cpe:2.3:a:cloudfoundry:cloud_foundry_uaa_bosh:24.1:*:*:*:*:*:*:*
    • cpe:2.3:a:cloudfoundry:cloud_foundry_uaa_bosh:24.2:*:*:*:*:*:*:*
    • cpe:2.3:a:cloudfoundry:cloud_foundry_uaa_bosh:24.3:*:*:*:*:*:*:*
    • cpe:2.3:a:cloudfoundry:cloud_foundry_uaa_bosh:24.4:*:*:*:*:*:*:*
    • cpe:2.3:a:cloudfoundry:cloud_foundry_uaa_bosh:24.5:*:*:*:*:*:*:*
    • cpe:2.3:a:cloudfoundry:cloud_foundry_uaa_bosh:24.6:*:*:*:*:*:*:*
    • cpe:2.3:a:cloudfoundry:cloud_foundry_uaa_bosh:24.7:*:*:*:*:*:*:*
    • cpe:2.3:a:cloudfoundry:cloud_foundry_uaa_bosh:30.1:*:*:*:*:*:*:*
    • cpe:2.3:a:cloudfoundry:cloud_foundry_uaa_bosh:30.2:*:*:*:*:*:*:*
    • cpe:2.3:a:cloudfoundry:cloud_foundry_uaa_bosh:30.3:*:*:*:*:*:*:*
  • cpe:2.3:a:pivotal_software:cloud_foundry_uaa:*:*:*:*:*:*:*:*+ 38 more
    • cpe:2.3:a:pivotal_software:cloud_foundry_uaa:*:*:*:*:*:*:*:*range: <=4.2.0
    • cpe:2.3:a:pivotal_software:cloud_foundry_uaa:2.2.5.4:*:*:*:*:*:*:*
    • cpe:2.3:a:pivotal_software:cloud_foundry_uaa:2.7.1:*:*:*:*:*:*:*
    • cpe:2.3:a:pivotal_software:cloud_foundry_uaa:2.7.2:*:*:*:*:*:*:*
    • cpe:2.3:a:pivotal_software:cloud_foundry_uaa:2.7.3:*:*:*:*:*:*:*
    • cpe:2.3:a:pivotal_software:cloud_foundry_uaa:2.7.4:*:*:*:*:*:*:*
    • cpe:2.3:a:pivotal_software:cloud_foundry_uaa:2.7.4.1:*:*:*:*:*:*:*
    • cpe:2.3:a:pivotal_software:cloud_foundry_uaa:2.7.4.11:*:*:*:*:*:*:*
    • cpe:2.3:a:pivotal_software:cloud_foundry_uaa:2.7.4.12:*:*:*:*:*:*:*
    • cpe:2.3:a:pivotal_software:cloud_foundry_uaa:2.7.4.13:*:*:*:*:*:*:*
    • cpe:2.3:a:pivotal_software:cloud_foundry_uaa:2.7.4.14:*:*:*:*:*:*:*
    • cpe:2.3:a:pivotal_software:cloud_foundry_uaa:2.7.4.2:*:*:*:*:*:*:*
    • cpe:2.3:a:pivotal_software:cloud_foundry_uaa:2.7.4.3:*:*:*:*:*:*:*
    • cpe:2.3:a:pivotal_software:cloud_foundry_uaa:2.7.4.4:*:*:*:*:*:*:*
    • cpe:2.3:a:pivotal_software:cloud_foundry_uaa:2.7.4.5:*:*:*:*:*:*:*
    • cpe:2.3:a:pivotal_software:cloud_foundry_uaa:2.7.4.6:*:*:*:*:*:*:*
    • cpe:2.3:a:pivotal_software:cloud_foundry_uaa:2.7.4.7:*:*:*:*:*:*:*
    • cpe:2.3:a:pivotal_software:cloud_foundry_uaa:2.7.4.8:*:*:*:*:*:*:*
    • cpe:2.3:a:pivotal_software:cloud_foundry_uaa:2.7.4.9:*:*:*:*:*:*:*
    • cpe:2.3:a:pivotal_software:cloud_foundry_uaa:3.6.1:*:*:*:*:*:*:*
    • cpe:2.3:a:pivotal_software:cloud_foundry_uaa:3.6.2:*:*:*:*:*:*:*
    • cpe:2.3:a:pivotal_software:cloud_foundry_uaa:3.6.3:*:*:*:*:*:*:*
    • cpe:2.3:a:pivotal_software:cloud_foundry_uaa:3.6.4:*:*:*:*:*:*:*
    • cpe:2.3:a:pivotal_software:cloud_foundry_uaa:3.6.5:*:*:*:*:*:*:*
    • cpe:2.3:a:pivotal_software:cloud_foundry_uaa:3.6.6:*:*:*:*:*:*:*
    • cpe:2.3:a:pivotal_software:cloud_foundry_uaa:3.6.7:*:*:*:*:*:*:*
    • cpe:2.3:a:pivotal_software:cloud_foundry_uaa:3.6.8:*:*:*:*:*:*:*
    • cpe:2.3:a:pivotal_software:cloud_foundry_uaa:3.9.1:*:*:*:*:*:*:*
    • cpe:2.3:a:pivotal_software:cloud_foundry_uaa:3.9.10:*:*:*:*:*:*:*
    • cpe:2.3:a:pivotal_software:cloud_foundry_uaa:3.9.12:*:*:*:*:*:*:*
    • cpe:2.3:a:pivotal_software:cloud_foundry_uaa:3.9.13:*:*:*:*:*:*:*
    • cpe:2.3:a:pivotal_software:cloud_foundry_uaa:3.9.2:*:*:*:*:*:*:*
    • cpe:2.3:a:pivotal_software:cloud_foundry_uaa:3.9.3:*:*:*:*:*:*:*
    • cpe:2.3:a:pivotal_software:cloud_foundry_uaa:3.9.4:*:*:*:*:*:*:*
    • cpe:2.3:a:pivotal_software:cloud_foundry_uaa:3.9.5:*:*:*:*:*:*:*
    • cpe:2.3:a:pivotal_software:cloud_foundry_uaa:3.9.6:*:*:*:*:*:*:*
    • cpe:2.3:a:pivotal_software:cloud_foundry_uaa:3.9.7:*:*:*:*:*:*:*
    • cpe:2.3:a:pivotal_software:cloud_foundry_uaa:3.9.8:*:*:*:*:*:*:*
    • cpe:2.3:a:pivotal_software:cloud_foundry_uaa:3.9.9:*:*:*:*:*:*:*
  • Range: Cloud Foundry UAA

Patches

5
2dbeb9e93e07

better parsing of attributes

https://github.com/cloudfoundry/uaaFilip HanikApr 19, 2017via ghsa
3 files changed · +188 5
  • server/src/main/java/org/cloudfoundry/identity/uaa/resources/jdbc/SimpleSearchQueryConverter.java+89 1 modified
    @@ -13,6 +13,7 @@
     
     package org.cloudfoundry.identity.uaa.resources.jdbc;
     
    +import com.unboundid.scim.sdk.InvalidResourceException;
     import com.unboundid.scim.sdk.SCIMException;
     import com.unboundid.scim.sdk.SCIMFilter;
     import org.apache.commons.logging.Log;
    @@ -25,19 +26,82 @@
     import java.text.DateFormat;
     import java.text.ParseException;
     import java.text.SimpleDateFormat;
    +import java.util.Arrays;
     import java.util.Collections;
     import java.util.HashMap;
    +import java.util.LinkedList;
    +import java.util.List;
     import java.util.Map;
     
    +import static java.util.Collections.emptyList;
    +import static java.util.Optional.ofNullable;
     import static org.cloudfoundry.identity.uaa.resources.jdbc.SearchQueryConverter.ProcessedFilter.ORDER_BY;
     
     public class SimpleSearchQueryConverter implements SearchQueryConverter {
     
    +    //LOWER
    +    public static final List<String> VALID_ATTRIBUTE_NAMES = Collections.unmodifiableList(
    +        Arrays.asList(
    +            "id",
    +            "created",
    +            "lastmodified",
    +            "version",
    +            "username",
    +            "password",
    +            "email",
    +            "givenname",
    +            "familyname",
    +            "name.familyname",
    +            "name.givenname",
    +            "active",
    +            "phonenumber",
    +            "verified",
    +            "origin",
    +            "identity_zone_id",
    +            "passwd_lastmodified",
    +            "passwd_change_required",
    +            "last_logon_success_time",
    +            "previous_logon_success_time",
    +            "displayname",
    +            "scope",
    +            "group_id",
    +            "member_id",
    +            "member_type",
    +            "description",
    +            "client_id",
    +            "authorized_grant_types",
    +            "web_server_redirect_uri",
    +            "redirect_uri",
    +            "access_token_validity",
    +            "refresh_token_validity",
    +            "autoapprove",
    +            "show_on_home_page",
    +            "created_by",
    +            "required_user_groups",
    +            "user_id",
    +            "meta.lastmodified",
    +            "meta.created",
    +            "meta.location",
    +            "meta.resourcetype",
    +            "meta.version",
    +            "emails.value",
    +            "groups.display",
    +            "phonenumbers.value",
    +            "gm.external_group",
    +            "gm.origin",
    +            "g.displayname",
    +            "g.id"
    +        )
    +    );
    +
         private static Log logger = LogFactory.getLog(SimpleSearchQueryConverter.class);
         private AttributeNameMapper mapper = new SimpleAttributeNameMapper(Collections.<String, String> emptyMap());
     
         private boolean dbCaseInsensitive = false;
     
    +    public SimpleSearchQueryConverter() {
    +    }
    +
         public boolean isDbCaseInsensitive() {
             return dbCaseInsensitive;
         }
    @@ -92,7 +156,7 @@ private String getWhereClause(String filter, String sortBy, boolean ascending, M
             }
         }
     
    -    private SCIMFilter scimFilter(String filter) throws SCIMException {
    +    protected SCIMFilter scimFilter(String filter) throws SCIMException {
             SCIMFilter scimFilter;
             try {
                 scimFilter = SCIMFilter.parse(filter);
    @@ -101,9 +165,33 @@ private SCIMFilter scimFilter(String filter) throws SCIMException {
                 filter = filter.replaceAll("'","\"");
                 scimFilter = SCIMFilter.parse(filter);
             }
    +        validateFilterAttributes(scimFilter);
             return scimFilter;
         }
     
    +    private void validateFilterAttributes(SCIMFilter filter) throws SCIMException {
    +        List<String> invalidAttributes = new LinkedList<>();
    +        validateFilterAttributes(filter, invalidAttributes);
    +        if (!invalidAttributes.isEmpty()) {
    +            throw new InvalidResourceException("Invalid filter attributes:"+StringUtils.collectionToCommaDelimitedString(invalidAttributes));
    +        }
    +    }
    +
    +    private void validateFilterAttributes(SCIMFilter filter, List<String> invalidAttribues) {
    +        if (filter.getFilterAttribute()!=null && filter.getFilterAttribute().getAttributeName()!=null) {
    +            String name = filter.getFilterAttribute().getAttributeName();
    +            if (filter.getFilterAttribute().getSubAttributeName()!=null) {
    +                name = name + "." + filter.getFilterAttribute().getSubAttributeName();
    +            }
    +            if (!VALID_ATTRIBUTE_NAMES.contains(name.toLowerCase())) {
    +                invalidAttribues.add(name);
    +            }
    +        }
    +        for (SCIMFilter subfilter : ofNullable(filter.getFilterComponents()).orElse(emptyList())) {
    +            validateFilterAttributes(subfilter, invalidAttribues);
    +        }
    +    }
    +
         private String createFilter(SCIMFilter filter, Map<String,Object> values, AttributeNameMapper mapper, String paramPrefix) {
             switch (filter.getFilterType()) {
                 case AND:
    
  • server/src/test/java/org/cloudfoundry/identity/uaa/resources/jdbc/SimpleSearchQueryConverterTests.java+95 0 added
    @@ -0,0 +1,95 @@
    +/*
    + * ****************************************************************************
    + *     Cloud Foundry
    + *     Copyright (c) [2009-2017] Pivotal Software, Inc. All Rights Reserved.
    + *
    + *     This product is licensed to you under the Apache License, Version 2.0 (the "License").
    + *     You may not use this product except in compliance with the License.
    + *
    + *     This product includes a number of subcomponents with
    + *     separate copyright notices and license terms. Your use of these
    + *     subcomponents is subject to the terms and conditions of the
    + *     subcomponent's license, as noted in the LICENSE file.
    + * ****************************************************************************
    + */
    +
    +package org.cloudfoundry.identity.uaa.resources.jdbc;
    +
    +import com.unboundid.scim.sdk.InvalidResourceException;
    +import com.unboundid.scim.sdk.SCIMFilter;
    +import org.cloudfoundry.identity.uaa.scim.jdbc.ScimSearchQueryConverter;
    +import org.junit.Before;
    +import org.junit.Rule;
    +import org.junit.Test;
    +import org.junit.rules.ExpectedException;
    +
    +import java.util.concurrent.atomic.AtomicInteger;
    +
    +import static java.util.Collections.emptyList;
    +import static java.util.Optional.ofNullable;
    +import static org.hamcrest.Matchers.containsString;
    +import static org.hamcrest.Matchers.startsWith;
    +
    +public class SimpleSearchQueryConverterTests {
    +
    +    SimpleSearchQueryConverter converter;
    +
    +    String query = "user_id eq \"7e2345e8-8bbf-4eaa-9bc3-ae1ba610f890\"" +
    +        "and " +
    +        "client_id eq \"app\"" +
    +        "and " +
    +        "meta.lastmodified gt \"some-value\"" +
    +        "and " +
    +        "(an/**/invalid/**/attribute/**/and/**/1" + //invalid attribute name
    +        " pr " + //operator (present)
    +        "and "
    +        + "1 eq 1)" + //invalid attribute name 1
    +        " and " +
    +        "\"1\" eq \"1\"";
    +
    +    String validQuery = "user_id eq \"7e2345e8-8bbf-4eaa-9bc3-ae1ba610f890\"" +
    +        "and " +
    +        "client_id eq \"app\"" +
    +        "and " +
    +        "meta.lastmodified gt \"some-value\"" +
    +        "and " +
    +        "meta.created pr";
    +
    +    @Rule
    +    public ExpectedException exception = ExpectedException.none();
    +
    +    @Before
    +    public void setup() {
    +        converter = new ScimSearchQueryConverter();
    +    }
    +
    +    @Test
    +    public void test_query() throws Exception {
    +        exception.expect(InvalidResourceException.class);
    +        exception.expectMessage(startsWith("Invalid filter attributes"));
    +        exception.expectMessage(containsString("an/**/invalid/**/attribute/**/and/**/1"));
    +        exception.expectMessage(containsString("1"));
    +        exception.expectMessage(containsString("\"1\""));
    +        SCIMFilter filter = converter.scimFilter(query);
    +    }
    +
    +    @Test
    +    public void print_query() throws Exception {
    +        SCIMFilter filter = converter.scimFilter(validQuery);
    +        printFilterAttributes(filter, new AtomicInteger(0));
    +    }
    +
    +    public void printFilterAttributes(SCIMFilter filter, AtomicInteger pos) {
    +        if (filter.getFilterAttribute() != null) {
    +            String name = filter.getFilterAttribute().getAttributeName();
    +            if (filter.getFilterAttribute().getSubAttributeName() != null) {
    +                name = name + "." + filter.getFilterAttribute().getSubAttributeName();
    +            }
    +            System.out.println((pos.incrementAndGet()) + ". Attribute name:" + name);
    +        }
    +        for (SCIMFilter subfilter : ofNullable(filter.getFilterComponents()).orElse(emptyList())) {
    +            printFilterAttributes(subfilter, pos);
    +        }
    +    }
    +
    +}
    \ No newline at end of file
    
  • server/src/test/java/org/cloudfoundry/identity/uaa/scim/jdbc/ScimSearchQueryConverterTests.java+4 4 modified
    @@ -58,8 +58,8 @@ public void canConvertValidFilters() throws Exception {
             validate(filterProcessor.convert("username pr and emails.value co \".com\"", null, false),"(username IS NOT NULL AND LOWER(email) LIKE LOWER(:__value_0))", 1);
             validate(filterProcessor.convert("username eq \"joe\" or emails.value co \".com\"", null, false),"(LOWER(username) = LOWER(:__value_0) OR LOWER(email) LIKE LOWER(:__value_1))", 2);
             validate(filterProcessor.convert("active eq true", null, false),"active = :__value_0", 1, Boolean.class);
    -        validate(filterProcessor.convert("test eq 1000000.45", null, false),"test = :__value_0", 1, Double.class);
    -        validate(filterProcessor.convert("test eq 1000000", null, false),"test = :__value_0", 1, Double.class);
    +        validate(filterProcessor.convert("Version eq 1000000.45", null, false),"Version = :__value_0", 1, Double.class);
    +        validate(filterProcessor.convert("meta.VerSion eq 1000000", null, false),"VerSion = :__value_0", 1, Double.class);
         }
     
         @Test
    @@ -84,8 +84,8 @@ public void caseInsensitiveDbDoesNotInjectLower() throws Exception {
             validate(filterProcessor.convert("username pr and emails.value co \".com\"", null, false),"(username IS NOT NULL AND email LIKE :__value_0)", 1);
             validate(filterProcessor.convert("username eq \"joe\" or emails.value co \".com\"", null, false),"(username = :__value_0 OR email LIKE :__value_1)", 2);
             validate(filterProcessor.convert("active eq true", null, false),"active = :__value_0", 1, Boolean.class);
    -        validate(filterProcessor.convert("test eq 1000000.45", null, false),"test = :__value_0", 1, Double.class);
    -        validate(filterProcessor.convert("test eq 1000000", null, false),"test = :__value_0", 1, Double.class);
    +        validate(filterProcessor.convert("Version eq 1000000.45", null, false),"Version = :__value_0", 1, Double.class);
    +        validate(filterProcessor.convert("meta.VerSion eq 1000000", null, false),"VerSion = :__value_0", 1, Double.class);
         }
     
         @Test
    
01edea6337c8

better parsing of attributes

https://github.com/cloudfoundry/uaaFilip HanikApr 19, 2017via ghsa
4 files changed · +296 14
  • common/src/main/java/org/cloudfoundry/identity/uaa/rest/jdbc/SimpleSearchQueryConverter.java+103 10 modified
    @@ -1,6 +1,6 @@
     /*******************************************************************************
      *     Cloud Foundry
    - *     Copyright (c) [2009-2014] Pivotal Software, Inc. All Rights Reserved.
    + *     Copyright (c) [2009-2016] Pivotal Software, Inc. All Rights Reserved.
      *
      *     This product is licensed to you under the Apache License, Version 2.0 (the "License").
      *     You may not use this product except in compliance with the License.
    @@ -13,13 +13,7 @@
     
     package org.cloudfoundry.identity.uaa.rest.jdbc;
     
    -import java.text.DateFormat;
    -import java.text.ParseException;
    -import java.text.SimpleDateFormat;
    -import java.util.Collections;
    -import java.util.HashMap;
    -import java.util.Map;
    -
    +import com.unboundid.scim.sdk.InvalidResourceException;
     import com.unboundid.scim.sdk.SCIMException;
     import com.unboundid.scim.sdk.SCIMFilter;
     import org.apache.commons.logging.Log;
    @@ -29,15 +23,85 @@
     import org.springframework.security.oauth2.common.util.RandomValueStringGenerator;
     import org.springframework.util.StringUtils;
     
    +import java.text.DateFormat;
    +import java.text.ParseException;
    +import java.text.SimpleDateFormat;
    +import java.util.Arrays;
    +import java.util.Collections;
    +import java.util.HashMap;
    +import java.util.LinkedList;
    +import java.util.List;
    +import java.util.Map;
    +
    +import static java.util.Collections.emptyList;
    +import static java.util.Optional.ofNullable;
     import static org.cloudfoundry.identity.uaa.rest.jdbc.SearchQueryConverter.ProcessedFilter.ORDER_BY;
     
     public class SimpleSearchQueryConverter implements SearchQueryConverter {
     
    +    //LOWER
    +    public static final List<String> VALID_ATTRIBUTE_NAMES = Collections.unmodifiableList(
    +        Arrays.asList(
    +            "id",
    +            "created",
    +            "lastmodified",
    +            "version",
    +            "username",
    +            "password",
    +            "email",
    +            "givenname",
    +            "familyname",
    +            "name.familyname",
    +            "name.givenname",
    +            "active",
    +            "phonenumber",
    +            "verified",
    +            "origin",
    +            "identity_zone_id",
    +            "passwd_lastmodified",
    +            "passwd_change_required",
    +            "last_logon_success_time",
    +            "previous_logon_success_time",
    +            "displayname",
    +            "scope",
    +            "group_id",
    +            "member_id",
    +            "member_type",
    +            "description",
    +            "client_id",
    +            "authorized_grant_types",
    +            "web_server_redirect_uri",
    +            "redirect_uri",
    +            "access_token_validity",
    +            "refresh_token_validity",
    +            "autoapprove",
    +            "show_on_home_page",
    +            "created_by",
    +            "required_user_groups",
    +            "user_id",
    +            "meta.lastmodified",
    +            "meta.created",
    +            "meta.location",
    +            "meta.resourcetype",
    +            "meta.version",
    +            "emails.value",
    +            "groups.display",
    +            "phonenumbers.value",
    +            "gm.external_group",
    +            "gm.origin",
    +            "g.displayname",
    +            "g.id"
    +        )
    +    );
    +
         private static Log logger = LogFactory.getLog(SimpleSearchQueryConverter.class);
         private AttributeNameMapper mapper = new SimpleAttributeNameMapper(Collections.<String, String> emptyMap());
     
         private boolean dbCaseInsensitive = false;
     
    +    public SimpleSearchQueryConverter() {
    +    }
    +
         public boolean isDbCaseInsensitive() {
             return dbCaseInsensitive;
         }
    @@ -92,7 +156,7 @@ private String getWhereClause(String filter, String sortBy, boolean ascending, M
             }
         }
     
    -    private SCIMFilter scimFilter(String filter) throws SCIMException {
    +    protected SCIMFilter scimFilter(String filter) throws SCIMException {
             SCIMFilter scimFilter;
             try {
                 scimFilter = SCIMFilter.parse(filter);
    @@ -101,9 +165,33 @@ private SCIMFilter scimFilter(String filter) throws SCIMException {
                 filter = filter.replaceAll("'","\"");
                 scimFilter = SCIMFilter.parse(filter);
             }
    +        validateFilterAttributes(scimFilter);
             return scimFilter;
         }
     
    +    private void validateFilterAttributes(SCIMFilter filter) throws SCIMException {
    +        List<String> invalidAttributes = new LinkedList<>();
    +        validateFilterAttributes(filter, invalidAttributes);
    +        if (!invalidAttributes.isEmpty()) {
    +            throw new InvalidResourceException("Invalid filter attributes:"+StringUtils.collectionToCommaDelimitedString(invalidAttributes));
    +        }
    +    }
    +
    +    private void validateFilterAttributes(SCIMFilter filter, List<String> invalidAttribues) {
    +        if (filter.getFilterAttribute()!=null && filter.getFilterAttribute().getAttributeName()!=null) {
    +            String name = filter.getFilterAttribute().getAttributeName();
    +            if (filter.getFilterAttribute().getSubAttributeName()!=null) {
    +                name = name + "." + filter.getFilterAttribute().getSubAttributeName();
    +            }
    +            if (!VALID_ATTRIBUTE_NAMES.contains(name.toLowerCase())) {
    +                invalidAttribues.add(name);
    +            }
    +        }
    +        for (SCIMFilter subfilter : ofNullable(filter.getFilterComponents()).orElse(emptyList())) {
    +            validateFilterAttributes(subfilter, invalidAttribues);
    +        }
    +    }
    +
         private String createFilter(SCIMFilter filter, Map<String,Object> values, AttributeNameMapper mapper, String paramPrefix) {
             switch (filter.getFilterType()) {
                 case AND:
    @@ -130,7 +218,12 @@ private String createFilter(SCIMFilter filter, Map<String,Object> values, Attrib
             return null;
         }
     
    -    protected String comparisonClause(SCIMFilter filter, String comparator, Map<String, Object> values, String valuePrefix, String valueSuffix, String paramPrefix) {
    +    protected String comparisonClause(SCIMFilter filter,
    +                                      String comparator,
    +                                      Map<String, Object> values,
    +                                      String valuePrefix,
    +                                      String valueSuffix,
    +                                      String paramPrefix) {
             String pName = getParamName(values, paramPrefix);
             String paramName = ":"+pName;
             if (filter.getFilterValue() == null) {
    
  • common/src/test/java/org/cloudfoundry/identity/uaa/rest/jdbc/SimpleSearchQueryConverterTests.java+94 0 added
    @@ -0,0 +1,94 @@
    +/*
    + * ****************************************************************************
    + *     Cloud Foundry
    + *     Copyright (c) [2009-2017] Pivotal Software, Inc. All Rights Reserved.
    + *
    + *     This product is licensed to you under the Apache License, Version 2.0 (the "License").
    + *     You may not use this product except in compliance with the License.
    + *
    + *     This product includes a number of subcomponents with
    + *     separate copyright notices and license terms. Your use of these
    + *     subcomponents is subject to the terms and conditions of the
    + *     subcomponent's license, as noted in the LICENSE file.
    + * ****************************************************************************
    + */
    +
    +package org.cloudfoundry.identity.uaa.rest.jdbc;
    +
    +import com.unboundid.scim.sdk.InvalidResourceException;
    +import com.unboundid.scim.sdk.SCIMFilter;
    +import org.junit.Before;
    +import org.junit.Rule;
    +import org.junit.Test;
    +import org.junit.rules.ExpectedException;
    +
    +import java.util.concurrent.atomic.AtomicInteger;
    +
    +import static java.util.Collections.emptyList;
    +import static java.util.Optional.ofNullable;
    +import static org.hamcrest.Matchers.containsString;
    +import static org.hamcrest.Matchers.startsWith;
    +
    +public class SimpleSearchQueryConverterTests {
    +
    +    SimpleSearchQueryConverter converter;
    +
    +    String query = "user_id eq \"7e2345e8-8bbf-4eaa-9bc3-ae1ba610f890\"" +
    +        "and " +
    +        "client_id eq \"app\"" +
    +        "and " +
    +        "meta.lastmodified gt \"some-value\"" +
    +        "and " +
    +        "(an/**/invalid/**/attribute/**/and/**/1" + //invalid attribute name
    +        " pr " + //operator (present)
    +        "and "
    +        + "1 eq 1)" + //invalid attribute name 1
    +        " and " +
    +        "\"1\" eq \"1\"";
    +
    +    String validQuery = "user_id eq \"7e2345e8-8bbf-4eaa-9bc3-ae1ba610f890\"" +
    +        "and " +
    +        "client_id eq \"app\"" +
    +        "and " +
    +        "meta.lastmodified gt \"some-value\"" +
    +        "and " +
    +        "meta.created pr";
    +
    +    @Rule
    +    public ExpectedException exception = ExpectedException.none();
    +
    +    @Before
    +    public void setup() {
    +        converter = new SimpleSearchQueryConverter();
    +    }
    +
    +    @Test
    +    public void test_query() throws Exception {
    +        exception.expect(InvalidResourceException.class);
    +        exception.expectMessage(startsWith("Invalid filter attributes"));
    +        exception.expectMessage(containsString("an/**/invalid/**/attribute/**/and/**/1"));
    +        exception.expectMessage(containsString("1"));
    +        exception.expectMessage(containsString("\"1\""));
    +        SCIMFilter filter = converter.scimFilter(query);
    +    }
    +
    +    @Test
    +    public void print_query() throws Exception {
    +        SCIMFilter filter = converter.scimFilter(validQuery);
    +        printFilterAttributes(filter, new AtomicInteger(0));
    +    }
    +
    +    public void printFilterAttributes(SCIMFilter filter, AtomicInteger pos) {
    +        if (filter.getFilterAttribute() != null) {
    +            String name = filter.getFilterAttribute().getAttributeName();
    +            if (filter.getFilterAttribute().getSubAttributeName() != null) {
    +                name = name + "." + filter.getFilterAttribute().getSubAttributeName();
    +            }
    +            System.out.println((pos.incrementAndGet()) + ". Attribute name:" + name);
    +        }
    +        for (SCIMFilter subfilter : ofNullable(filter.getFilterComponents()).orElse(emptyList())) {
    +            printFilterAttributes(subfilter, pos);
    +        }
    +    }
    +
    +}
    \ No newline at end of file
    
  • scim/src/test/java/org/cloudfoundry/identity/uaa/scim/jdbc/ScimSearchQueryConverterTests.java+4 4 modified
    @@ -58,8 +58,8 @@ public void canConvertValidFilters() throws Exception {
             validate(filterProcessor.convert("username pr and emails.value co \".com\"", null, false),"(username IS NOT NULL AND LOWER(email) LIKE LOWER(:__value_0))", 1);
             validate(filterProcessor.convert("username eq \"joe\" or emails.value co \".com\"", null, false),"(LOWER(username) = LOWER(:__value_0) OR LOWER(email) LIKE LOWER(:__value_1))", 2);
             validate(filterProcessor.convert("active eq true", null, false),"active = :__value_0", 1, Boolean.class);
    -        validate(filterProcessor.convert("test eq 1000000.45", null, false),"test = :__value_0", 1, Double.class);
    -        validate(filterProcessor.convert("test eq 1000000", null, false),"test = :__value_0", 1, Double.class);
    +        validate(filterProcessor.convert("Version eq 1000000.45", null, false),"Version = :__value_0", 1, Double.class);
    +        validate(filterProcessor.convert("meta.VerSion eq 1000000", null, false),"VerSion = :__value_0", 1, Double.class);
         }
     
         @Test
    @@ -84,8 +84,8 @@ public void caseInsensitiveDbDoesNotInjectLower() throws Exception {
             validate(filterProcessor.convert("username pr and emails.value co \".com\"", null, false),"(username IS NOT NULL AND email LIKE :__value_0)", 1);
             validate(filterProcessor.convert("username eq \"joe\" or emails.value co \".com\"", null, false),"(username = :__value_0 OR email LIKE :__value_1)", 2);
             validate(filterProcessor.convert("active eq true", null, false),"active = :__value_0", 1, Boolean.class);
    -        validate(filterProcessor.convert("test eq 1000000.45", null, false),"test = :__value_0", 1, Double.class);
    -        validate(filterProcessor.convert("test eq 1000000", null, false),"test = :__value_0", 1, Double.class);
    +        validate(filterProcessor.convert("Version eq 1000000.45", null, false),"Version = :__value_0", 1, Double.class);
    +        validate(filterProcessor.convert("meta.VerSion eq 1000000", null, false),"VerSion = :__value_0", 1, Double.class);
         }
     
         @Test
    
  • server/src/test/java/org/cloudfoundry/identity/uaa/resources/jdbc/SimpleSearchQueryConverterTests.java+95 0 added
    @@ -0,0 +1,95 @@
    +/*
    + * ****************************************************************************
    + *     Cloud Foundry
    + *     Copyright (c) [2009-2017] Pivotal Software, Inc. All Rights Reserved.
    + *
    + *     This product is licensed to you under the Apache License, Version 2.0 (the "License").
    + *     You may not use this product except in compliance with the License.
    + *
    + *     This product includes a number of subcomponents with
    + *     separate copyright notices and license terms. Your use of these
    + *     subcomponents is subject to the terms and conditions of the
    + *     subcomponent's license, as noted in the LICENSE file.
    + * ****************************************************************************
    + */
    +
    +package org.cloudfoundry.identity.uaa.resources.jdbc;
    +
    +import com.unboundid.scim.sdk.InvalidResourceException;
    +import com.unboundid.scim.sdk.SCIMFilter;
    +import org.cloudfoundry.identity.uaa.scim.jdbc.ScimSearchQueryConverter;
    +import org.junit.Before;
    +import org.junit.Rule;
    +import org.junit.Test;
    +import org.junit.rules.ExpectedException;
    +
    +import java.util.concurrent.atomic.AtomicInteger;
    +
    +import static java.util.Collections.emptyList;
    +import static java.util.Optional.ofNullable;
    +import static org.hamcrest.Matchers.containsString;
    +import static org.hamcrest.Matchers.startsWith;
    +
    +public class SimpleSearchQueryConverterTests {
    +
    +    SimpleSearchQueryConverter converter;
    +
    +    String query = "user_id eq \"7e2345e8-8bbf-4eaa-9bc3-ae1ba610f890\"" +
    +        "and " +
    +        "client_id eq \"app\"" +
    +        "and " +
    +        "meta.lastmodified gt \"some-value\"" +
    +        "and " +
    +        "(an/**/invalid/**/attribute/**/and/**/1" + //invalid attribute name
    +        " pr " + //operator (present)
    +        "and "
    +        + "1 eq 1)" + //invalid attribute name 1
    +        " and " +
    +        "\"1\" eq \"1\"";
    +
    +    String validQuery = "user_id eq \"7e2345e8-8bbf-4eaa-9bc3-ae1ba610f890\"" +
    +        "and " +
    +        "client_id eq \"app\"" +
    +        "and " +
    +        "meta.lastmodified gt \"some-value\"" +
    +        "and " +
    +        "meta.created pr";
    +
    +    @Rule
    +    public ExpectedException exception = ExpectedException.none();
    +
    +    @Before
    +    public void setup() {
    +        converter = new ScimSearchQueryConverter();
    +    }
    +
    +    @Test
    +    public void test_query() throws Exception {
    +        exception.expect(InvalidResourceException.class);
    +        exception.expectMessage(startsWith("Invalid filter attributes"));
    +        exception.expectMessage(containsString("an/**/invalid/**/attribute/**/and/**/1"));
    +        exception.expectMessage(containsString("1"));
    +        exception.expectMessage(containsString("\"1\""));
    +        SCIMFilter filter = converter.scimFilter(query);
    +    }
    +
    +    @Test
    +    public void print_query() throws Exception {
    +        SCIMFilter filter = converter.scimFilter(validQuery);
    +        printFilterAttributes(filter, new AtomicInteger(0));
    +    }
    +
    +    public void printFilterAttributes(SCIMFilter filter, AtomicInteger pos) {
    +        if (filter.getFilterAttribute() != null) {
    +            String name = filter.getFilterAttribute().getAttributeName();
    +            if (filter.getFilterAttribute().getSubAttributeName() != null) {
    +                name = name + "." + filter.getFilterAttribute().getSubAttributeName();
    +            }
    +            System.out.println((pos.incrementAndGet()) + ". Attribute name:" + name);
    +        }
    +        for (SCIMFilter subfilter : ofNullable(filter.getFilterComponents()).orElse(emptyList())) {
    +            printFilterAttributes(subfilter, pos);
    +        }
    +    }
    +
    +}
    \ No newline at end of file
    
5dc5ca9176ed

better parsing of attributes

https://github.com/cloudfoundry/uaaFilip HanikApr 19, 2017via ghsa
3 files changed · +201 13
  • server/src/main/java/org/cloudfoundry/identity/uaa/resources/jdbc/SimpleSearchQueryConverter.java+102 9 modified
    @@ -13,13 +13,7 @@
     
     package org.cloudfoundry.identity.uaa.resources.jdbc;
     
    -import java.text.DateFormat;
    -import java.text.ParseException;
    -import java.text.SimpleDateFormat;
    -import java.util.Collections;
    -import java.util.HashMap;
    -import java.util.Map;
    -
    +import com.unboundid.scim.sdk.InvalidResourceException;
     import com.unboundid.scim.sdk.SCIMException;
     import com.unboundid.scim.sdk.SCIMFilter;
     import org.apache.commons.logging.Log;
    @@ -29,15 +23,85 @@
     import org.springframework.security.oauth2.common.util.RandomValueStringGenerator;
     import org.springframework.util.StringUtils;
     
    +import java.text.DateFormat;
    +import java.text.ParseException;
    +import java.text.SimpleDateFormat;
    +import java.util.Arrays;
    +import java.util.Collections;
    +import java.util.HashMap;
    +import java.util.LinkedList;
    +import java.util.List;
    +import java.util.Map;
    +
    +import static java.util.Collections.emptyList;
    +import static java.util.Optional.ofNullable;
     import static org.cloudfoundry.identity.uaa.resources.jdbc.SearchQueryConverter.ProcessedFilter.ORDER_BY;
     
     public class SimpleSearchQueryConverter implements SearchQueryConverter {
     
    +    //LOWER
    +    public static final List<String> VALID_ATTRIBUTE_NAMES = Collections.unmodifiableList(
    +        Arrays.asList(
    +            "id",
    +            "created",
    +            "lastmodified",
    +            "version",
    +            "username",
    +            "password",
    +            "email",
    +            "givenname",
    +            "familyname",
    +            "name.familyname",
    +            "name.givenname",
    +            "active",
    +            "phonenumber",
    +            "verified",
    +            "origin",
    +            "identity_zone_id",
    +            "passwd_lastmodified",
    +            "passwd_change_required",
    +            "last_logon_success_time",
    +            "previous_logon_success_time",
    +            "displayname",
    +            "scope",
    +            "group_id",
    +            "member_id",
    +            "member_type",
    +            "description",
    +            "client_id",
    +            "authorized_grant_types",
    +            "web_server_redirect_uri",
    +            "redirect_uri",
    +            "access_token_validity",
    +            "refresh_token_validity",
    +            "autoapprove",
    +            "show_on_home_page",
    +            "created_by",
    +            "required_user_groups",
    +            "user_id",
    +            "meta.lastmodified",
    +            "meta.created",
    +            "meta.location",
    +            "meta.resourcetype",
    +            "meta.version",
    +            "emails.value",
    +            "groups.display",
    +            "phonenumbers.value",
    +            "gm.external_group",
    +            "gm.origin",
    +            "g.displayname",
    +            "g.id"
    +        )
    +    );
    +
         private static Log logger = LogFactory.getLog(SimpleSearchQueryConverter.class);
         private AttributeNameMapper mapper = new SimpleAttributeNameMapper(Collections.<String, String> emptyMap());
     
         private boolean dbCaseInsensitive = false;
     
    +    public SimpleSearchQueryConverter() {
    +    }
    +
         public boolean isDbCaseInsensitive() {
             return dbCaseInsensitive;
         }
    @@ -92,7 +156,7 @@ private String getWhereClause(String filter, String sortBy, boolean ascending, M
             }
         }
     
    -    private SCIMFilter scimFilter(String filter) throws SCIMException {
    +    protected SCIMFilter scimFilter(String filter) throws SCIMException {
             SCIMFilter scimFilter;
             try {
                 scimFilter = SCIMFilter.parse(filter);
    @@ -101,9 +165,33 @@ private SCIMFilter scimFilter(String filter) throws SCIMException {
                 filter = filter.replaceAll("'","\"");
                 scimFilter = SCIMFilter.parse(filter);
             }
    +        validateFilterAttributes(scimFilter);
             return scimFilter;
         }
     
    +    private void validateFilterAttributes(SCIMFilter filter) throws SCIMException {
    +        List<String> invalidAttributes = new LinkedList<>();
    +        validateFilterAttributes(filter, invalidAttributes);
    +        if (!invalidAttributes.isEmpty()) {
    +            throw new InvalidResourceException("Invalid filter attributes:"+StringUtils.collectionToCommaDelimitedString(invalidAttributes));
    +        }
    +    }
    +
    +    private void validateFilterAttributes(SCIMFilter filter, List<String> invalidAttribues) {
    +        if (filter.getFilterAttribute()!=null && filter.getFilterAttribute().getAttributeName()!=null) {
    +            String name = filter.getFilterAttribute().getAttributeName();
    +            if (filter.getFilterAttribute().getSubAttributeName()!=null) {
    +                name = name + "." + filter.getFilterAttribute().getSubAttributeName();
    +            }
    +            if (!VALID_ATTRIBUTE_NAMES.contains(name.toLowerCase())) {
    +                invalidAttribues.add(name);
    +            }
    +        }
    +        for (SCIMFilter subfilter : ofNullable(filter.getFilterComponents()).orElse(emptyList())) {
    +            validateFilterAttributes(subfilter, invalidAttribues);
    +        }
    +    }
    +
         private String createFilter(SCIMFilter filter, Map<String,Object> values, AttributeNameMapper mapper, String paramPrefix) {
             switch (filter.getFilterType()) {
                 case AND:
    @@ -130,7 +218,12 @@ private String createFilter(SCIMFilter filter, Map<String,Object> values, Attrib
             return null;
         }
     
    -    protected String comparisonClause(SCIMFilter filter, String comparator, Map<String, Object> values, String valuePrefix, String valueSuffix, String paramPrefix) {
    +    protected String comparisonClause(SCIMFilter filter,
    +                                      String comparator,
    +                                      Map<String, Object> values,
    +                                      String valuePrefix,
    +                                      String valueSuffix,
    +                                      String paramPrefix) {
             String pName = getParamName(values, paramPrefix);
             String paramName = ":"+pName;
             if (filter.getFilterValue() == null) {
    
  • server/src/test/java/org/cloudfoundry/identity/uaa/resources/jdbc/SimpleSearchQueryConverterTests.java+95 0 added
    @@ -0,0 +1,95 @@
    +/*
    + * ****************************************************************************
    + *     Cloud Foundry
    + *     Copyright (c) [2009-2017] Pivotal Software, Inc. All Rights Reserved.
    + *
    + *     This product is licensed to you under the Apache License, Version 2.0 (the "License").
    + *     You may not use this product except in compliance with the License.
    + *
    + *     This product includes a number of subcomponents with
    + *     separate copyright notices and license terms. Your use of these
    + *     subcomponents is subject to the terms and conditions of the
    + *     subcomponent's license, as noted in the LICENSE file.
    + * ****************************************************************************
    + */
    +
    +package org.cloudfoundry.identity.uaa.resources.jdbc;
    +
    +import com.unboundid.scim.sdk.InvalidResourceException;
    +import com.unboundid.scim.sdk.SCIMFilter;
    +import org.cloudfoundry.identity.uaa.scim.jdbc.ScimSearchQueryConverter;
    +import org.junit.Before;
    +import org.junit.Rule;
    +import org.junit.Test;
    +import org.junit.rules.ExpectedException;
    +
    +import java.util.concurrent.atomic.AtomicInteger;
    +
    +import static java.util.Collections.emptyList;
    +import static java.util.Optional.ofNullable;
    +import static org.hamcrest.Matchers.containsString;
    +import static org.hamcrest.Matchers.startsWith;
    +
    +public class SimpleSearchQueryConverterTests {
    +
    +    SimpleSearchQueryConverter converter;
    +
    +    String query = "user_id eq \"7e2345e8-8bbf-4eaa-9bc3-ae1ba610f890\"" +
    +        "and " +
    +        "client_id eq \"app\"" +
    +        "and " +
    +        "meta.lastmodified gt \"some-value\"" +
    +        "and " +
    +        "(an/**/invalid/**/attribute/**/and/**/1" + //invalid attribute name
    +        " pr " + //operator (present)
    +        "and "
    +        + "1 eq 1)" + //invalid attribute name 1
    +        " and " +
    +        "\"1\" eq \"1\"";
    +
    +    String validQuery = "user_id eq \"7e2345e8-8bbf-4eaa-9bc3-ae1ba610f890\"" +
    +        "and " +
    +        "client_id eq \"app\"" +
    +        "and " +
    +        "meta.lastmodified gt \"some-value\"" +
    +        "and " +
    +        "meta.created pr";
    +
    +    @Rule
    +    public ExpectedException exception = ExpectedException.none();
    +
    +    @Before
    +    public void setup() {
    +        converter = new ScimSearchQueryConverter();
    +    }
    +
    +    @Test
    +    public void test_query() throws Exception {
    +        exception.expect(InvalidResourceException.class);
    +        exception.expectMessage(startsWith("Invalid filter attributes"));
    +        exception.expectMessage(containsString("an/**/invalid/**/attribute/**/and/**/1"));
    +        exception.expectMessage(containsString("1"));
    +        exception.expectMessage(containsString("\"1\""));
    +        SCIMFilter filter = converter.scimFilter(query);
    +    }
    +
    +    @Test
    +    public void print_query() throws Exception {
    +        SCIMFilter filter = converter.scimFilter(validQuery);
    +        printFilterAttributes(filter, new AtomicInteger(0));
    +    }
    +
    +    public void printFilterAttributes(SCIMFilter filter, AtomicInteger pos) {
    +        if (filter.getFilterAttribute() != null) {
    +            String name = filter.getFilterAttribute().getAttributeName();
    +            if (filter.getFilterAttribute().getSubAttributeName() != null) {
    +                name = name + "." + filter.getFilterAttribute().getSubAttributeName();
    +            }
    +            System.out.println((pos.incrementAndGet()) + ". Attribute name:" + name);
    +        }
    +        for (SCIMFilter subfilter : ofNullable(filter.getFilterComponents()).orElse(emptyList())) {
    +            printFilterAttributes(subfilter, pos);
    +        }
    +    }
    +
    +}
    \ No newline at end of file
    
  • server/src/test/java/org/cloudfoundry/identity/uaa/scim/jdbc/ScimSearchQueryConverterTests.java+4 4 modified
    @@ -58,8 +58,8 @@ public void canConvertValidFilters() throws Exception {
             validate(filterProcessor.convert("username pr and emails.value co \".com\"", null, false),"(username IS NOT NULL AND LOWER(email) LIKE LOWER(:__value_0))", 1);
             validate(filterProcessor.convert("username eq \"joe\" or emails.value co \".com\"", null, false),"(LOWER(username) = LOWER(:__value_0) OR LOWER(email) LIKE LOWER(:__value_1))", 2);
             validate(filterProcessor.convert("active eq true", null, false),"active = :__value_0", 1, Boolean.class);
    -        validate(filterProcessor.convert("test eq 1000000.45", null, false),"test = :__value_0", 1, Double.class);
    -        validate(filterProcessor.convert("test eq 1000000", null, false),"test = :__value_0", 1, Double.class);
    +        validate(filterProcessor.convert("Version eq 1000000.45", null, false),"Version = :__value_0", 1, Double.class);
    +        validate(filterProcessor.convert("meta.VerSion eq 1000000", null, false),"VerSion = :__value_0", 1, Double.class);
         }
     
         @Test
    @@ -84,8 +84,8 @@ public void caseInsensitiveDbDoesNotInjectLower() throws Exception {
             validate(filterProcessor.convert("username pr and emails.value co \".com\"", null, false),"(username IS NOT NULL AND email LIKE :__value_0)", 1);
             validate(filterProcessor.convert("username eq \"joe\" or emails.value co \".com\"", null, false),"(username = :__value_0 OR email LIKE :__value_1)", 2);
             validate(filterProcessor.convert("active eq true", null, false),"active = :__value_0", 1, Boolean.class);
    -        validate(filterProcessor.convert("test eq 1000000.45", null, false),"test = :__value_0", 1, Double.class);
    -        validate(filterProcessor.convert("test eq 1000000", null, false),"test = :__value_0", 1, Double.class);
    +        validate(filterProcessor.convert("Version eq 1000000.45", null, false),"Version = :__value_0", 1, Double.class);
    +        validate(filterProcessor.convert("meta.VerSion eq 1000000", null, false),"VerSion = :__value_0", 1, Double.class);
         }
     
         @Test
    
74b9b270787a

better parsing of attributes

https://github.com/cloudfoundry/uaaFilip HanikApr 19, 2017via ghsa
3 files changed · +201 13
  • server/src/main/java/org/cloudfoundry/identity/uaa/resources/jdbc/SimpleSearchQueryConverter.java+102 9 modified
    @@ -13,13 +13,7 @@
     
     package org.cloudfoundry.identity.uaa.resources.jdbc;
     
    -import java.text.DateFormat;
    -import java.text.ParseException;
    -import java.text.SimpleDateFormat;
    -import java.util.Collections;
    -import java.util.HashMap;
    -import java.util.Map;
    -
    +import com.unboundid.scim.sdk.InvalidResourceException;
     import com.unboundid.scim.sdk.SCIMException;
     import com.unboundid.scim.sdk.SCIMFilter;
     import org.apache.commons.logging.Log;
    @@ -29,15 +23,85 @@
     import org.springframework.security.oauth2.common.util.RandomValueStringGenerator;
     import org.springframework.util.StringUtils;
     
    +import java.text.DateFormat;
    +import java.text.ParseException;
    +import java.text.SimpleDateFormat;
    +import java.util.Arrays;
    +import java.util.Collections;
    +import java.util.HashMap;
    +import java.util.LinkedList;
    +import java.util.List;
    +import java.util.Map;
    +
    +import static java.util.Collections.emptyList;
    +import static java.util.Optional.ofNullable;
     import static org.cloudfoundry.identity.uaa.resources.jdbc.SearchQueryConverter.ProcessedFilter.ORDER_BY;
     
     public class SimpleSearchQueryConverter implements SearchQueryConverter {
     
    +    //LOWER
    +    public static final List<String> VALID_ATTRIBUTE_NAMES = Collections.unmodifiableList(
    +        Arrays.asList(
    +            "id",
    +            "created",
    +            "lastmodified",
    +            "version",
    +            "username",
    +            "password",
    +            "email",
    +            "givenname",
    +            "familyname",
    +            "name.familyname",
    +            "name.givenname",
    +            "active",
    +            "phonenumber",
    +            "verified",
    +            "origin",
    +            "identity_zone_id",
    +            "passwd_lastmodified",
    +            "passwd_change_required",
    +            "last_logon_success_time",
    +            "previous_logon_success_time",
    +            "displayname",
    +            "scope",
    +            "group_id",
    +            "member_id",
    +            "member_type",
    +            "description",
    +            "client_id",
    +            "authorized_grant_types",
    +            "web_server_redirect_uri",
    +            "redirect_uri",
    +            "access_token_validity",
    +            "refresh_token_validity",
    +            "autoapprove",
    +            "show_on_home_page",
    +            "created_by",
    +            "required_user_groups",
    +            "user_id",
    +            "meta.lastmodified",
    +            "meta.created",
    +            "meta.location",
    +            "meta.resourcetype",
    +            "meta.version",
    +            "emails.value",
    +            "groups.display",
    +            "phonenumbers.value",
    +            "gm.external_group",
    +            "gm.origin",
    +            "g.displayname",
    +            "g.id"
    +        )
    +    );
    +
         private static Log logger = LogFactory.getLog(SimpleSearchQueryConverter.class);
         private AttributeNameMapper mapper = new SimpleAttributeNameMapper(Collections.<String, String> emptyMap());
     
         private boolean dbCaseInsensitive = false;
     
    +    public SimpleSearchQueryConverter() {
    +    }
    +
         public boolean isDbCaseInsensitive() {
             return dbCaseInsensitive;
         }
    @@ -92,7 +156,7 @@ private String getWhereClause(String filter, String sortBy, boolean ascending, M
             }
         }
     
    -    private SCIMFilter scimFilter(String filter) throws SCIMException {
    +    protected SCIMFilter scimFilter(String filter) throws SCIMException {
             SCIMFilter scimFilter;
             try {
                 scimFilter = SCIMFilter.parse(filter);
    @@ -101,9 +165,33 @@ private SCIMFilter scimFilter(String filter) throws SCIMException {
                 filter = filter.replaceAll("'","\"");
                 scimFilter = SCIMFilter.parse(filter);
             }
    +        validateFilterAttributes(scimFilter);
             return scimFilter;
         }
     
    +    private void validateFilterAttributes(SCIMFilter filter) throws SCIMException {
    +        List<String> invalidAttributes = new LinkedList<>();
    +        validateFilterAttributes(filter, invalidAttributes);
    +        if (!invalidAttributes.isEmpty()) {
    +            throw new InvalidResourceException("Invalid filter attributes:"+StringUtils.collectionToCommaDelimitedString(invalidAttributes));
    +        }
    +    }
    +
    +    private void validateFilterAttributes(SCIMFilter filter, List<String> invalidAttribues) {
    +        if (filter.getFilterAttribute()!=null && filter.getFilterAttribute().getAttributeName()!=null) {
    +            String name = filter.getFilterAttribute().getAttributeName();
    +            if (filter.getFilterAttribute().getSubAttributeName()!=null) {
    +                name = name + "." + filter.getFilterAttribute().getSubAttributeName();
    +            }
    +            if (!VALID_ATTRIBUTE_NAMES.contains(name.toLowerCase())) {
    +                invalidAttribues.add(name);
    +            }
    +        }
    +        for (SCIMFilter subfilter : ofNullable(filter.getFilterComponents()).orElse(emptyList())) {
    +            validateFilterAttributes(subfilter, invalidAttribues);
    +        }
    +    }
    +
         private String createFilter(SCIMFilter filter, Map<String,Object> values, AttributeNameMapper mapper, String paramPrefix) {
             switch (filter.getFilterType()) {
                 case AND:
    @@ -130,7 +218,12 @@ private String createFilter(SCIMFilter filter, Map<String,Object> values, Attrib
             return null;
         }
     
    -    protected String comparisonClause(SCIMFilter filter, String comparator, Map<String, Object> values, String valuePrefix, String valueSuffix, String paramPrefix) {
    +    protected String comparisonClause(SCIMFilter filter,
    +                                      String comparator,
    +                                      Map<String, Object> values,
    +                                      String valuePrefix,
    +                                      String valueSuffix,
    +                                      String paramPrefix) {
             String pName = getParamName(values, paramPrefix);
             String paramName = ":"+pName;
             if (filter.getFilterValue() == null) {
    
  • server/src/test/java/org/cloudfoundry/identity/uaa/resources/jdbc/SimpleSearchQueryConverterTests.java+95 0 added
    @@ -0,0 +1,95 @@
    +/*
    + * ****************************************************************************
    + *     Cloud Foundry
    + *     Copyright (c) [2009-2017] Pivotal Software, Inc. All Rights Reserved.
    + *
    + *     This product is licensed to you under the Apache License, Version 2.0 (the "License").
    + *     You may not use this product except in compliance with the License.
    + *
    + *     This product includes a number of subcomponents with
    + *     separate copyright notices and license terms. Your use of these
    + *     subcomponents is subject to the terms and conditions of the
    + *     subcomponent's license, as noted in the LICENSE file.
    + * ****************************************************************************
    + */
    +
    +package org.cloudfoundry.identity.uaa.resources.jdbc;
    +
    +import com.unboundid.scim.sdk.InvalidResourceException;
    +import com.unboundid.scim.sdk.SCIMFilter;
    +import org.cloudfoundry.identity.uaa.scim.jdbc.ScimSearchQueryConverter;
    +import org.junit.Before;
    +import org.junit.Rule;
    +import org.junit.Test;
    +import org.junit.rules.ExpectedException;
    +
    +import java.util.concurrent.atomic.AtomicInteger;
    +
    +import static java.util.Collections.emptyList;
    +import static java.util.Optional.ofNullable;
    +import static org.hamcrest.Matchers.containsString;
    +import static org.hamcrest.Matchers.startsWith;
    +
    +public class SimpleSearchQueryConverterTests {
    +
    +    SimpleSearchQueryConverter converter;
    +
    +    String query = "user_id eq \"7e2345e8-8bbf-4eaa-9bc3-ae1ba610f890\"" +
    +        "and " +
    +        "client_id eq \"app\"" +
    +        "and " +
    +        "meta.lastmodified gt \"some-value\"" +
    +        "and " +
    +        "(an/**/invalid/**/attribute/**/and/**/1" + //invalid attribute name
    +        " pr " + //operator (present)
    +        "and "
    +        + "1 eq 1)" + //invalid attribute name 1
    +        " and " +
    +        "\"1\" eq \"1\"";
    +
    +    String validQuery = "user_id eq \"7e2345e8-8bbf-4eaa-9bc3-ae1ba610f890\"" +
    +        "and " +
    +        "client_id eq \"app\"" +
    +        "and " +
    +        "meta.lastmodified gt \"some-value\"" +
    +        "and " +
    +        "meta.created pr";
    +
    +    @Rule
    +    public ExpectedException exception = ExpectedException.none();
    +
    +    @Before
    +    public void setup() {
    +        converter = new ScimSearchQueryConverter();
    +    }
    +
    +    @Test
    +    public void test_query() throws Exception {
    +        exception.expect(InvalidResourceException.class);
    +        exception.expectMessage(startsWith("Invalid filter attributes"));
    +        exception.expectMessage(containsString("an/**/invalid/**/attribute/**/and/**/1"));
    +        exception.expectMessage(containsString("1"));
    +        exception.expectMessage(containsString("\"1\""));
    +        SCIMFilter filter = converter.scimFilter(query);
    +    }
    +
    +    @Test
    +    public void print_query() throws Exception {
    +        SCIMFilter filter = converter.scimFilter(validQuery);
    +        printFilterAttributes(filter, new AtomicInteger(0));
    +    }
    +
    +    public void printFilterAttributes(SCIMFilter filter, AtomicInteger pos) {
    +        if (filter.getFilterAttribute() != null) {
    +            String name = filter.getFilterAttribute().getAttributeName();
    +            if (filter.getFilterAttribute().getSubAttributeName() != null) {
    +                name = name + "." + filter.getFilterAttribute().getSubAttributeName();
    +            }
    +            System.out.println((pos.incrementAndGet()) + ". Attribute name:" + name);
    +        }
    +        for (SCIMFilter subfilter : ofNullable(filter.getFilterComponents()).orElse(emptyList())) {
    +            printFilterAttributes(subfilter, pos);
    +        }
    +    }
    +
    +}
    \ No newline at end of file
    
  • server/src/test/java/org/cloudfoundry/identity/uaa/scim/jdbc/ScimSearchQueryConverterTests.java+4 4 modified
    @@ -58,8 +58,8 @@ public void canConvertValidFilters() throws Exception {
             validate(filterProcessor.convert("username pr and emails.value co \".com\"", null, false),"(username IS NOT NULL AND LOWER(email) LIKE LOWER(:__value_0))", 1);
             validate(filterProcessor.convert("username eq \"joe\" or emails.value co \".com\"", null, false),"(LOWER(username) = LOWER(:__value_0) OR LOWER(email) LIKE LOWER(:__value_1))", 2);
             validate(filterProcessor.convert("active eq true", null, false),"active = :__value_0", 1, Boolean.class);
    -        validate(filterProcessor.convert("test eq 1000000.45", null, false),"test = :__value_0", 1, Double.class);
    -        validate(filterProcessor.convert("test eq 1000000", null, false),"test = :__value_0", 1, Double.class);
    +        validate(filterProcessor.convert("Version eq 1000000.45", null, false),"Version = :__value_0", 1, Double.class);
    +        validate(filterProcessor.convert("meta.VerSion eq 1000000", null, false),"VerSion = :__value_0", 1, Double.class);
         }
     
         @Test
    @@ -84,8 +84,8 @@ public void caseInsensitiveDbDoesNotInjectLower() throws Exception {
             validate(filterProcessor.convert("username pr and emails.value co \".com\"", null, false),"(username IS NOT NULL AND email LIKE :__value_0)", 1);
             validate(filterProcessor.convert("username eq \"joe\" or emails.value co \".com\"", null, false),"(username = :__value_0 OR email LIKE :__value_1)", 2);
             validate(filterProcessor.convert("active eq true", null, false),"active = :__value_0", 1, Boolean.class);
    -        validate(filterProcessor.convert("test eq 1000000.45", null, false),"test = :__value_0", 1, Double.class);
    -        validate(filterProcessor.convert("test eq 1000000", null, false),"test = :__value_0", 1, Double.class);
    +        validate(filterProcessor.convert("Version eq 1000000.45", null, false),"Version = :__value_0", 1, Double.class);
    +        validate(filterProcessor.convert("meta.VerSion eq 1000000", null, false),"VerSion = :__value_0", 1, Double.class);
         }
     
         @Test
    
b6d6526cb891

better parsing of attributes

https://github.com/cloudfoundry/uaaFilip HanikApr 19, 2017via ghsa
3 files changed · +201 13
  • server/src/main/java/org/cloudfoundry/identity/uaa/resources/jdbc/SimpleSearchQueryConverter.java+102 9 modified
    @@ -13,13 +13,7 @@
     
     package org.cloudfoundry.identity.uaa.resources.jdbc;
     
    -import java.text.DateFormat;
    -import java.text.ParseException;
    -import java.text.SimpleDateFormat;
    -import java.util.Collections;
    -import java.util.HashMap;
    -import java.util.Map;
    -
    +import com.unboundid.scim.sdk.InvalidResourceException;
     import com.unboundid.scim.sdk.SCIMException;
     import com.unboundid.scim.sdk.SCIMFilter;
     import org.apache.commons.logging.Log;
    @@ -29,15 +23,85 @@
     import org.springframework.security.oauth2.common.util.RandomValueStringGenerator;
     import org.springframework.util.StringUtils;
     
    +import java.text.DateFormat;
    +import java.text.ParseException;
    +import java.text.SimpleDateFormat;
    +import java.util.Arrays;
    +import java.util.Collections;
    +import java.util.HashMap;
    +import java.util.LinkedList;
    +import java.util.List;
    +import java.util.Map;
    +
    +import static java.util.Collections.emptyList;
    +import static java.util.Optional.ofNullable;
     import static org.cloudfoundry.identity.uaa.resources.jdbc.SearchQueryConverter.ProcessedFilter.ORDER_BY;
     
     public class SimpleSearchQueryConverter implements SearchQueryConverter {
     
    +    //LOWER
    +    public static final List<String> VALID_ATTRIBUTE_NAMES = Collections.unmodifiableList(
    +        Arrays.asList(
    +            "id",
    +            "created",
    +            "lastmodified",
    +            "version",
    +            "username",
    +            "password",
    +            "email",
    +            "givenname",
    +            "familyname",
    +            "name.familyname",
    +            "name.givenname",
    +            "active",
    +            "phonenumber",
    +            "verified",
    +            "origin",
    +            "identity_zone_id",
    +            "passwd_lastmodified",
    +            "passwd_change_required",
    +            "last_logon_success_time",
    +            "previous_logon_success_time",
    +            "displayname",
    +            "scope",
    +            "group_id",
    +            "member_id",
    +            "member_type",
    +            "description",
    +            "client_id",
    +            "authorized_grant_types",
    +            "web_server_redirect_uri",
    +            "redirect_uri",
    +            "access_token_validity",
    +            "refresh_token_validity",
    +            "autoapprove",
    +            "show_on_home_page",
    +            "created_by",
    +            "required_user_groups",
    +            "user_id",
    +            "meta.lastmodified",
    +            "meta.created",
    +            "meta.location",
    +            "meta.resourcetype",
    +            "meta.version",
    +            "emails.value",
    +            "groups.display",
    +            "phonenumbers.value",
    +            "gm.external_group",
    +            "gm.origin",
    +            "g.displayname",
    +            "g.id"
    +        )
    +    );
    +
         private static Log logger = LogFactory.getLog(SimpleSearchQueryConverter.class);
         private AttributeNameMapper mapper = new SimpleAttributeNameMapper(Collections.<String, String> emptyMap());
     
         private boolean dbCaseInsensitive = false;
     
    +    public SimpleSearchQueryConverter() {
    +    }
    +
         public boolean isDbCaseInsensitive() {
             return dbCaseInsensitive;
         }
    @@ -92,7 +156,7 @@ private String getWhereClause(String filter, String sortBy, boolean ascending, M
             }
         }
     
    -    private SCIMFilter scimFilter(String filter) throws SCIMException {
    +    protected SCIMFilter scimFilter(String filter) throws SCIMException {
             SCIMFilter scimFilter;
             try {
                 scimFilter = SCIMFilter.parse(filter);
    @@ -101,9 +165,33 @@ private SCIMFilter scimFilter(String filter) throws SCIMException {
                 filter = filter.replaceAll("'","\"");
                 scimFilter = SCIMFilter.parse(filter);
             }
    +        validateFilterAttributes(scimFilter);
             return scimFilter;
         }
     
    +    private void validateFilterAttributes(SCIMFilter filter) throws SCIMException {
    +        List<String> invalidAttributes = new LinkedList<>();
    +        validateFilterAttributes(filter, invalidAttributes);
    +        if (!invalidAttributes.isEmpty()) {
    +            throw new InvalidResourceException("Invalid filter attributes:"+StringUtils.collectionToCommaDelimitedString(invalidAttributes));
    +        }
    +    }
    +
    +    private void validateFilterAttributes(SCIMFilter filter, List<String> invalidAttribues) {
    +        if (filter.getFilterAttribute()!=null && filter.getFilterAttribute().getAttributeName()!=null) {
    +            String name = filter.getFilterAttribute().getAttributeName();
    +            if (filter.getFilterAttribute().getSubAttributeName()!=null) {
    +                name = name + "." + filter.getFilterAttribute().getSubAttributeName();
    +            }
    +            if (!VALID_ATTRIBUTE_NAMES.contains(name.toLowerCase())) {
    +                invalidAttribues.add(name);
    +            }
    +        }
    +        for (SCIMFilter subfilter : ofNullable(filter.getFilterComponents()).orElse(emptyList())) {
    +            validateFilterAttributes(subfilter, invalidAttribues);
    +        }
    +    }
    +
         private String createFilter(SCIMFilter filter, Map<String,Object> values, AttributeNameMapper mapper, String paramPrefix) {
             switch (filter.getFilterType()) {
                 case AND:
    @@ -130,7 +218,12 @@ private String createFilter(SCIMFilter filter, Map<String,Object> values, Attrib
             return null;
         }
     
    -    protected String comparisonClause(SCIMFilter filter, String comparator, Map<String, Object> values, String valuePrefix, String valueSuffix, String paramPrefix) {
    +    protected String comparisonClause(SCIMFilter filter,
    +                                      String comparator,
    +                                      Map<String, Object> values,
    +                                      String valuePrefix,
    +                                      String valueSuffix,
    +                                      String paramPrefix) {
             String pName = getParamName(values, paramPrefix);
             String paramName = ":"+pName;
             if (filter.getFilterValue() == null) {
    
  • server/src/test/java/org/cloudfoundry/identity/uaa/resources/jdbc/SimpleSearchQueryConverterTests.java+95 0 added
    @@ -0,0 +1,95 @@
    +/*
    + * ****************************************************************************
    + *     Cloud Foundry
    + *     Copyright (c) [2009-2017] Pivotal Software, Inc. All Rights Reserved.
    + *
    + *     This product is licensed to you under the Apache License, Version 2.0 (the "License").
    + *     You may not use this product except in compliance with the License.
    + *
    + *     This product includes a number of subcomponents with
    + *     separate copyright notices and license terms. Your use of these
    + *     subcomponents is subject to the terms and conditions of the
    + *     subcomponent's license, as noted in the LICENSE file.
    + * ****************************************************************************
    + */
    +
    +package org.cloudfoundry.identity.uaa.resources.jdbc;
    +
    +import com.unboundid.scim.sdk.InvalidResourceException;
    +import com.unboundid.scim.sdk.SCIMFilter;
    +import org.cloudfoundry.identity.uaa.scim.jdbc.ScimSearchQueryConverter;
    +import org.junit.Before;
    +import org.junit.Rule;
    +import org.junit.Test;
    +import org.junit.rules.ExpectedException;
    +
    +import java.util.concurrent.atomic.AtomicInteger;
    +
    +import static java.util.Collections.emptyList;
    +import static java.util.Optional.ofNullable;
    +import static org.hamcrest.Matchers.containsString;
    +import static org.hamcrest.Matchers.startsWith;
    +
    +public class SimpleSearchQueryConverterTests {
    +
    +    SimpleSearchQueryConverter converter;
    +
    +    String query = "user_id eq \"7e2345e8-8bbf-4eaa-9bc3-ae1ba610f890\"" +
    +        "and " +
    +        "client_id eq \"app\"" +
    +        "and " +
    +        "meta.lastmodified gt \"some-value\"" +
    +        "and " +
    +        "(an/**/invalid/**/attribute/**/and/**/1" + //invalid attribute name
    +        " pr " + //operator (present)
    +        "and "
    +        + "1 eq 1)" + //invalid attribute name 1
    +        " and " +
    +        "\"1\" eq \"1\"";
    +
    +    String validQuery = "user_id eq \"7e2345e8-8bbf-4eaa-9bc3-ae1ba610f890\"" +
    +        "and " +
    +        "client_id eq \"app\"" +
    +        "and " +
    +        "meta.lastmodified gt \"some-value\"" +
    +        "and " +
    +        "meta.created pr";
    +
    +    @Rule
    +    public ExpectedException exception = ExpectedException.none();
    +
    +    @Before
    +    public void setup() {
    +        converter = new ScimSearchQueryConverter();
    +    }
    +
    +    @Test
    +    public void test_query() throws Exception {
    +        exception.expect(InvalidResourceException.class);
    +        exception.expectMessage(startsWith("Invalid filter attributes"));
    +        exception.expectMessage(containsString("an/**/invalid/**/attribute/**/and/**/1"));
    +        exception.expectMessage(containsString("1"));
    +        exception.expectMessage(containsString("\"1\""));
    +        SCIMFilter filter = converter.scimFilter(query);
    +    }
    +
    +    @Test
    +    public void print_query() throws Exception {
    +        SCIMFilter filter = converter.scimFilter(validQuery);
    +        printFilterAttributes(filter, new AtomicInteger(0));
    +    }
    +
    +    public void printFilterAttributes(SCIMFilter filter, AtomicInteger pos) {
    +        if (filter.getFilterAttribute() != null) {
    +            String name = filter.getFilterAttribute().getAttributeName();
    +            if (filter.getFilterAttribute().getSubAttributeName() != null) {
    +                name = name + "." + filter.getFilterAttribute().getSubAttributeName();
    +            }
    +            System.out.println((pos.incrementAndGet()) + ". Attribute name:" + name);
    +        }
    +        for (SCIMFilter subfilter : ofNullable(filter.getFilterComponents()).orElse(emptyList())) {
    +            printFilterAttributes(subfilter, pos);
    +        }
    +    }
    +
    +}
    \ No newline at end of file
    
  • server/src/test/java/org/cloudfoundry/identity/uaa/scim/jdbc/ScimSearchQueryConverterTests.java+4 4 modified
    @@ -58,8 +58,8 @@ public void canConvertValidFilters() throws Exception {
             validate(filterProcessor.convert("username pr and emails.value co \".com\"", null, false),"(username IS NOT NULL AND LOWER(email) LIKE LOWER(:__value_0))", 1);
             validate(filterProcessor.convert("username eq \"joe\" or emails.value co \".com\"", null, false),"(LOWER(username) = LOWER(:__value_0) OR LOWER(email) LIKE LOWER(:__value_1))", 2);
             validate(filterProcessor.convert("active eq true", null, false),"active = :__value_0", 1, Boolean.class);
    -        validate(filterProcessor.convert("test eq 1000000.45", null, false),"test = :__value_0", 1, Double.class);
    -        validate(filterProcessor.convert("test eq 1000000", null, false),"test = :__value_0", 1, Double.class);
    +        validate(filterProcessor.convert("Version eq 1000000.45", null, false),"Version = :__value_0", 1, Double.class);
    +        validate(filterProcessor.convert("meta.VerSion eq 1000000", null, false),"VerSion = :__value_0", 1, Double.class);
         }
     
         @Test
    @@ -84,8 +84,8 @@ public void caseInsensitiveDbDoesNotInjectLower() throws Exception {
             validate(filterProcessor.convert("username pr and emails.value co \".com\"", null, false),"(username IS NOT NULL AND email LIKE :__value_0)", 1);
             validate(filterProcessor.convert("username eq \"joe\" or emails.value co \".com\"", null, false),"(username = :__value_0 OR email LIKE :__value_1)", 2);
             validate(filterProcessor.convert("active eq true", null, false),"active = :__value_0", 1, Boolean.class);
    -        validate(filterProcessor.convert("test eq 1000000.45", null, false),"test = :__value_0", 1, Double.class);
    -        validate(filterProcessor.convert("test eq 1000000", null, false),"test = :__value_0", 1, Double.class);
    +        validate(filterProcessor.convert("Version eq 1000000.45", null, false),"Version = :__value_0", 1, Double.class);
    +        validate(filterProcessor.convert("meta.VerSion eq 1000000", null, false),"VerSion = :__value_0", 1, Double.class);
         }
     
         @Test
    

Vulnerability mechanics

Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

11

News mentions

0

No linked articles in our index yet.