You are viewing a plain text version of this content. The canonical link for it is here.
Posted to fortress@directory.apache.org by Chris Pike <cl...@psu.edu> on 2017/02/08 14:01:14 UTC

Filter Escapes

Shawn,

Ran into an issue yesterday where a role name had parenthesis in the name, and this messed up the fortress ldap filter when getting permissions for a user through the access manager. It appears filter params aren't being property escaped. Not sure if it is specific to this case or is present in other places as well. Thoughts?

~Chris

Re: Filter Escapes

Posted by Shawn McKinney <sm...@apache.org>.
agreed

> On Feb 9, 2017, at 3:30 PM, Chris Pike <cl...@psu.edu> wrote:
> 
> I think the issue is that the findPermission method in PermDAO is not calling the encodeSafeText method before adding the role name to the filter
> 
> https://github.com/apache/directory-fortress-core/blob/master/src/main/java/org/apache/directory/fortress/core/impl/PermDAO.java#L1906
> 
> 
> 
> 
> ----- Original Message -----
> From: "Shawn McKinney" <sm...@apache.org>
> To: fortress@directory.apache.org
> Sent: Thursday, February 9, 2017 3:23:22 PM
> Subject: Re: Filter Escapes
> 
> this is the method I am talking about that encodes filters on behalf of fortress searches:
>    /**
>     * Perform encoding on supplied input string for certain unsafe ascii characters.  These chars may be unsafe
>     * because ldap reserves some characters as operands.  Safe encoding safeguards from malicious scripting input errors 
>     * that are possible if data filtering did not get performed before being passed into dao layer.
>     *
>     * @param filter contains the data to filter.
>     * @return possibly modified input string for matched characters.
>     */
>    protected String escapeLDAPSearchFilter( String filter )
>    {
> 
> 
> obviously for this to work you would have to encode the value of the role name when the entity is created.  Seems like a lot of complexity to allow a that character in the field name, but again I’ll let you decide if its worthwhile.
> 
> Shawn
> 
>> On Feb 9, 2017, at 1:59 PM, Shawn McKinney <sm...@apache.org> wrote:
>> 
>> Chris as I’m sure you know, parenthesis are used by ldap search filters to establish precedence of operations.  You can look into encoding the value of the role name.  I’m surprised it isn’t already as passing unencoded strings into ldap is considered a security vulnerability, and many of the values passed into ldap are encoded.  
>> 
>> My view is role names probably shouldn’t have parenthesis in the names but I don’t have strong enough feelings to discourage its use by others.  That is to say if you have good reasons for doing it, you should be able to encode that value prior to storing / searching for it.
>> 
>> Shawn
>> 
>>> On Feb 9, 2017, at 1:20 PM, Chris Pike <cl...@psu.edu> wrote:
>>> 
>>> It's an LdapProtocolErrorException, the offending role name is something like "Test Role (development)" and the error printed looks something like
>>> 
>>> org.apache.directory.api.ldap.model.exception.LdapProtocolErrorException: The filter (&(objectClass=ftOperation)(|(ftUsers=userId)(ftRoles=Test Role (development)))) is invalid
>>> 
>>> 
>>> 
>>> 
>>> ----- Original Message -----
>>> From: "Emmanuel Lécharny" <el...@gmail.com>
>>> To: fortress@directory.apache.org
>>> Sent: Thursday, February 9, 2017 5:11:33 AM
>>> Subject: Re: Filter Escapes
>>> 
>>> Le 09/02/2017 à 01:59, Shawn McKinney a écrit :
>>>>> On Feb 8, 2017, at 8:01 AM, Chris Pike <cl...@psu.edu> wrote:
>>>>> 
>>>>> Ran into an issue yesterday where a role name had parenthesis in the name, and this messed up the fortress ldap filter when getting permissions for a user through the access manager. It appears filter params aren't being property escaped. Not sure if it is specific to this case or is present in other places as well. Thoughts?
>>>> Hi Chris,
>>>> 
>>>> what is the error you receive?  
>>> 
>>> In any case, you have two ways to build a filter :
>>> - use a String, and parse it
>>> - use the LDAP API filter Node elements (like EqualityNode), and get the
>>> resulting String
>>> 
>>> In the first case, each Filter element's value has to be encoded so that
>>> it's not going to interact with the filtre structure (ie, every '(' and
>>> ')' have to be escaped, and a few more chars too).
>>> 
>>> This can be done using FilterEncoder.encodeFilterValue( String value )
>>> static method, which returns an encoded value.
>>> 
>>> For instance, if you want to create a filter for a equality on the 'cn'
>>> AttributeType, with a value of "ACME(tm)", which resulting filter is
>>> "(cn=ACME\\28tm\\29)", do that :
>>> 
>>>  String filterStr = String.format( "(%s=%s)", "cn",
>>> FilterEncoder.encodeFilterValue( "ACME(tm)" ) );
>>> 
>>> or
>>> 
>>>  String filterStr = new EqualityNode<>( "cn", new StringValue(
>>> "ACME(tm)" ) ).toString();
>>> 
>>> 
>>> Both resulting filterStr will be valid (ie the "(cn=ACME\\28tm\\29)"
>>> String )
>>> 
>>> 
>>> -- 
>>> Emmanuel Lecharny
>>> 
>>> Symas.com
>>> directory.apache.org
>> 


Re: Filter Escapes

Posted by Chris Pike <cl...@psu.edu>.
I think the issue is that the findPermission method in PermDAO is not calling the encodeSafeText method before adding the role name to the filter

https://github.com/apache/directory-fortress-core/blob/master/src/main/java/org/apache/directory/fortress/core/impl/PermDAO.java#L1906




----- Original Message -----
From: "Shawn McKinney" <sm...@apache.org>
To: fortress@directory.apache.org
Sent: Thursday, February 9, 2017 3:23:22 PM
Subject: Re: Filter Escapes

this is the method I am talking about that encodes filters on behalf of fortress searches:
    /**
     * Perform encoding on supplied input string for certain unsafe ascii characters.  These chars may be unsafe
     * because ldap reserves some characters as operands.  Safe encoding safeguards from malicious scripting input errors 
     * that are possible if data filtering did not get performed before being passed into dao layer.
     *
     * @param filter contains the data to filter.
     * @return possibly modified input string for matched characters.
     */
    protected String escapeLDAPSearchFilter( String filter )
    {


obviously for this to work you would have to encode the value of the role name when the entity is created.  Seems like a lot of complexity to allow a that character in the field name, but again I’ll let you decide if its worthwhile.

Shawn

> On Feb 9, 2017, at 1:59 PM, Shawn McKinney <sm...@apache.org> wrote:
> 
> Chris as I’m sure you know, parenthesis are used by ldap search filters to establish precedence of operations.  You can look into encoding the value of the role name.  I’m surprised it isn’t already as passing unencoded strings into ldap is considered a security vulnerability, and many of the values passed into ldap are encoded.  
> 
> My view is role names probably shouldn’t have parenthesis in the names but I don’t have strong enough feelings to discourage its use by others.  That is to say if you have good reasons for doing it, you should be able to encode that value prior to storing / searching for it.
> 
> Shawn
> 
>> On Feb 9, 2017, at 1:20 PM, Chris Pike <cl...@psu.edu> wrote:
>> 
>> It's an LdapProtocolErrorException, the offending role name is something like "Test Role (development)" and the error printed looks something like
>> 
>> org.apache.directory.api.ldap.model.exception.LdapProtocolErrorException: The filter (&(objectClass=ftOperation)(|(ftUsers=userId)(ftRoles=Test Role (development)))) is invalid
>> 
>> 
>> 
>> 
>> ----- Original Message -----
>> From: "Emmanuel Lécharny" <el...@gmail.com>
>> To: fortress@directory.apache.org
>> Sent: Thursday, February 9, 2017 5:11:33 AM
>> Subject: Re: Filter Escapes
>> 
>> Le 09/02/2017 à 01:59, Shawn McKinney a écrit :
>>>> On Feb 8, 2017, at 8:01 AM, Chris Pike <cl...@psu.edu> wrote:
>>>> 
>>>> Ran into an issue yesterday where a role name had parenthesis in the name, and this messed up the fortress ldap filter when getting permissions for a user through the access manager. It appears filter params aren't being property escaped. Not sure if it is specific to this case or is present in other places as well. Thoughts?
>>> Hi Chris,
>>> 
>>> what is the error you receive?  
>> 
>> In any case, you have two ways to build a filter :
>> - use a String, and parse it
>> - use the LDAP API filter Node elements (like EqualityNode), and get the
>> resulting String
>> 
>> In the first case, each Filter element's value has to be encoded so that
>> it's not going to interact with the filtre structure (ie, every '(' and
>> ')' have to be escaped, and a few more chars too).
>> 
>> This can be done using FilterEncoder.encodeFilterValue( String value )
>> static method, which returns an encoded value.
>> 
>> For instance, if you want to create a filter for a equality on the 'cn'
>> AttributeType, with a value of "ACME(tm)", which resulting filter is
>> "(cn=ACME\\28tm\\29)", do that :
>> 
>>   String filterStr = String.format( "(%s=%s)", "cn",
>> FilterEncoder.encodeFilterValue( "ACME(tm)" ) );
>> 
>> or
>> 
>>   String filterStr = new EqualityNode<>( "cn", new StringValue(
>> "ACME(tm)" ) ).toString();
>> 
>> 
>> Both resulting filterStr will be valid (ie the "(cn=ACME\\28tm\\29)"
>> String )
>> 
>> 
>> -- 
>> Emmanuel Lecharny
>> 
>> Symas.com
>> directory.apache.org
>

Re: Filter Escapes

Posted by Shawn McKinney <sm...@apache.org>.
this is the method I am talking about that encodes filters on behalf of fortress searches:
    /**
     * Perform encoding on supplied input string for certain unsafe ascii characters.  These chars may be unsafe
     * because ldap reserves some characters as operands.  Safe encoding safeguards from malicious scripting input errors 
     * that are possible if data filtering did not get performed before being passed into dao layer.
     *
     * @param filter contains the data to filter.
     * @return possibly modified input string for matched characters.
     */
    protected String escapeLDAPSearchFilter( String filter )
    {


obviously for this to work you would have to encode the value of the role name when the entity is created.  Seems like a lot of complexity to allow a that character in the field name, but again I’ll let you decide if its worthwhile.

Shawn

> On Feb 9, 2017, at 1:59 PM, Shawn McKinney <sm...@apache.org> wrote:
> 
> Chris as I’m sure you know, parenthesis are used by ldap search filters to establish precedence of operations.  You can look into encoding the value of the role name.  I’m surprised it isn’t already as passing unencoded strings into ldap is considered a security vulnerability, and many of the values passed into ldap are encoded.  
> 
> My view is role names probably shouldn’t have parenthesis in the names but I don’t have strong enough feelings to discourage its use by others.  That is to say if you have good reasons for doing it, you should be able to encode that value prior to storing / searching for it.
> 
> Shawn
> 
>> On Feb 9, 2017, at 1:20 PM, Chris Pike <cl...@psu.edu> wrote:
>> 
>> It's an LdapProtocolErrorException, the offending role name is something like "Test Role (development)" and the error printed looks something like
>> 
>> org.apache.directory.api.ldap.model.exception.LdapProtocolErrorException: The filter (&(objectClass=ftOperation)(|(ftUsers=userId)(ftRoles=Test Role (development)))) is invalid
>> 
>> 
>> 
>> 
>> ----- Original Message -----
>> From: "Emmanuel Lécharny" <el...@gmail.com>
>> To: fortress@directory.apache.org
>> Sent: Thursday, February 9, 2017 5:11:33 AM
>> Subject: Re: Filter Escapes
>> 
>> Le 09/02/2017 à 01:59, Shawn McKinney a écrit :
>>>> On Feb 8, 2017, at 8:01 AM, Chris Pike <cl...@psu.edu> wrote:
>>>> 
>>>> Ran into an issue yesterday where a role name had parenthesis in the name, and this messed up the fortress ldap filter when getting permissions for a user through the access manager. It appears filter params aren't being property escaped. Not sure if it is specific to this case or is present in other places as well. Thoughts?
>>> Hi Chris,
>>> 
>>> what is the error you receive?  
>> 
>> In any case, you have two ways to build a filter :
>> - use a String, and parse it
>> - use the LDAP API filter Node elements (like EqualityNode), and get the
>> resulting String
>> 
>> In the first case, each Filter element's value has to be encoded so that
>> it's not going to interact with the filtre structure (ie, every '(' and
>> ')' have to be escaped, and a few more chars too).
>> 
>> This can be done using FilterEncoder.encodeFilterValue( String value )
>> static method, which returns an encoded value.
>> 
>> For instance, if you want to create a filter for a equality on the 'cn'
>> AttributeType, with a value of "ACME(tm)", which resulting filter is
>> "(cn=ACME\\28tm\\29)", do that :
>> 
>>   String filterStr = String.format( "(%s=%s)", "cn",
>> FilterEncoder.encodeFilterValue( "ACME(tm)" ) );
>> 
>> or
>> 
>>   String filterStr = new EqualityNode<>( "cn", new StringValue(
>> "ACME(tm)" ) ).toString();
>> 
>> 
>> Both resulting filterStr will be valid (ie the "(cn=ACME\\28tm\\29)"
>> String )
>> 
>> 
>> -- 
>> Emmanuel Lecharny
>> 
>> Symas.com
>> directory.apache.org
> 


Re: Filter Escapes

Posted by Shawn McKinney <sm...@apache.org>.
Chris as I’m sure you know, parenthesis are used by ldap search filters to establish precedence of operations.  You can look into encoding the value of the role name.  I’m surprised it isn’t already as passing unencoded strings into ldap is considered a security vulnerability, and many of the values passed into ldap are encoded.  

My view is role names probably shouldn’t have parenthesis in the names but I don’t have strong enough feelings to discourage its use by others.  That is to say if you have good reasons for doing it, you should be able to encode that value prior to storing / searching for it.

Shawn

> On Feb 9, 2017, at 1:20 PM, Chris Pike <cl...@psu.edu> wrote:
> 
> It's an LdapProtocolErrorException, the offending role name is something like "Test Role (development)" and the error printed looks something like
> 
> org.apache.directory.api.ldap.model.exception.LdapProtocolErrorException: The filter (&(objectClass=ftOperation)(|(ftUsers=userId)(ftRoles=Test Role (development)))) is invalid
> 
> 
> 
> 
> ----- Original Message -----
> From: "Emmanuel Lécharny" <el...@gmail.com>
> To: fortress@directory.apache.org
> Sent: Thursday, February 9, 2017 5:11:33 AM
> Subject: Re: Filter Escapes
> 
> Le 09/02/2017 à 01:59, Shawn McKinney a écrit :
>>> On Feb 8, 2017, at 8:01 AM, Chris Pike <cl...@psu.edu> wrote:
>>> 
>>> Ran into an issue yesterday where a role name had parenthesis in the name, and this messed up the fortress ldap filter when getting permissions for a user through the access manager. It appears filter params aren't being property escaped. Not sure if it is specific to this case or is present in other places as well. Thoughts?
>> Hi Chris,
>> 
>> what is the error you receive?  
> 
> In any case, you have two ways to build a filter :
> - use a String, and parse it
> - use the LDAP API filter Node elements (like EqualityNode), and get the
> resulting String
> 
> In the first case, each Filter element's value has to be encoded so that
> it's not going to interact with the filtre structure (ie, every '(' and
> ')' have to be escaped, and a few more chars too).
> 
> This can be done using FilterEncoder.encodeFilterValue( String value )
> static method, which returns an encoded value.
> 
> For instance, if you want to create a filter for a equality on the 'cn'
> AttributeType, with a value of "ACME(tm)", which resulting filter is
> "(cn=ACME\\28tm\\29)", do that :
> 
>    String filterStr = String.format( "(%s=%s)", "cn",
> FilterEncoder.encodeFilterValue( "ACME(tm)" ) );
> 
> or
> 
>    String filterStr = new EqualityNode<>( "cn", new StringValue(
> "ACME(tm)" ) ).toString();
> 
> 
> Both resulting filterStr will be valid (ie the "(cn=ACME\\28tm\\29)"
> String )
> 
> 
> -- 
> Emmanuel Lecharny
> 
> Symas.com
> directory.apache.org


Re: Filter Escapes

Posted by Chris Pike <cl...@psu.edu>.
It's an LdapProtocolErrorException, the offending role name is something like "Test Role (development)" and the error printed looks something like

org.apache.directory.api.ldap.model.exception.LdapProtocolErrorException: The filter (&(objectClass=ftOperation)(|(ftUsers=userId)(ftRoles=Test Role (development)))) is invalid




----- Original Message -----
From: "Emmanuel Lécharny" <el...@gmail.com>
To: fortress@directory.apache.org
Sent: Thursday, February 9, 2017 5:11:33 AM
Subject: Re: Filter Escapes

Le 09/02/2017 à 01:59, Shawn McKinney a écrit :
>> On Feb 8, 2017, at 8:01 AM, Chris Pike <cl...@psu.edu> wrote:
>>
>> Ran into an issue yesterday where a role name had parenthesis in the name, and this messed up the fortress ldap filter when getting permissions for a user through the access manager. It appears filter params aren't being property escaped. Not sure if it is specific to this case or is present in other places as well. Thoughts?
> Hi Chris,
>
> what is the error you receive?  

In any case, you have two ways to build a filter :
- use a String, and parse it
- use the LDAP API filter Node elements (like EqualityNode), and get the
resulting String

In the first case, each Filter element's value has to be encoded so that
it's not going to interact with the filtre structure (ie, every '(' and
')' have to be escaped, and a few more chars too).

This can be done using FilterEncoder.encodeFilterValue( String value )
static method, which returns an encoded value.

For instance, if you want to create a filter for a equality on the 'cn'
AttributeType, with a value of "ACME(tm)", which resulting filter is
"(cn=ACME\\28tm\\29)", do that :

    String filterStr = String.format( "(%s=%s)", "cn",
FilterEncoder.encodeFilterValue( "ACME(tm)" ) );

or

    String filterStr = new EqualityNode<>( "cn", new StringValue(
"ACME(tm)" ) ).toString();


Both resulting filterStr will be valid (ie the "(cn=ACME\\28tm\\29)"
String )


-- 
Emmanuel Lecharny

Symas.com
directory.apache.org

Re: Filter Escapes

Posted by Emmanuel Lécharny <el...@gmail.com>.

Le 09/02/2017 à 01:59, Shawn McKinney a écrit :
>> On Feb 8, 2017, at 8:01 AM, Chris Pike <cl...@psu.edu> wrote:
>>
>> Ran into an issue yesterday where a role name had parenthesis in the name, and this messed up the fortress ldap filter when getting permissions for a user through the access manager. It appears filter params aren't being property escaped. Not sure if it is specific to this case or is present in other places as well. Thoughts?
> Hi Chris,
>
> what is the error you receive?  

In any case, you have two ways to build a filter :
- use a String, and parse it
- use the LDAP API filter Node elements (like EqualityNode), and get the
resulting String

In the first case, each Filter element's value has to be encoded so that
it's not going to interact with the filtre structure (ie, every '(' and
')' have to be escaped, and a few more chars too).

This can be done using FilterEncoder.encodeFilterValue( String value )
static method, which returns an encoded value.

For instance, if you want to create a filter for a equality on the 'cn'
AttributeType, with a value of "ACME(tm)", which resulting filter is
"(cn=ACME\\28tm\\29)", do that :

    String filterStr = String.format( "(%s=%s)", "cn",
FilterEncoder.encodeFilterValue( "ACME(tm)" ) );

or

    String filterStr = new EqualityNode<>( "cn", new StringValue(
"ACME(tm)" ) ).toString();


Both resulting filterStr will be valid (ie the "(cn=ACME\\28tm\\29)"
String )


-- 
Emmanuel Lecharny

Symas.com
directory.apache.org


Re: Filter Escapes

Posted by Shawn McKinney <sm...@apache.org>.
> On Feb 8, 2017, at 8:01 AM, Chris Pike <cl...@psu.edu> wrote:
> 
> Ran into an issue yesterday where a role name had parenthesis in the name, and this messed up the fortress ldap filter when getting permissions for a user through the access manager. It appears filter params aren't being property escaped. Not sure if it is specific to this case or is present in other places as well. Thoughts?

Hi Chris,

what is the error you receive?