This site is the archived OWASP Foundation Wiki and is no longer accepting Account Requests.
To view the new OWASP Foundation website, please visit https://owasp.org
Difference between revisions of "Projects/OWASP Framework Security Project/Secure LDAP API Standard"
Line 1: | Line 1: | ||
− | This standard is designed to describe the | + | This standard is designed to describe the properties that secure LDAP client APIs exhibit. APIs with these properties help developers, regardless of their skill or experience with LDAP, avoid the most common and serious vulnerabilities associated with developing LDAP client software. |
'''Version: 0.1''' | '''Version: 0.1''' | ||
Line 5: | Line 5: | ||
'''Maintainer: [[User:TimMorgan|Timothy D. Morgan]]''' | '''Maintainer: [[User:TimMorgan|Timothy D. Morgan]]''' | ||
− | = Properties of Safe LDAP APIs = | + | = Properties of Safe LDAP Client APIs = |
− | == Documents the Security Risks of LDAP Filter Injection == | + | === Documents the Security Risks of LDAP Filter Injection === |
The API documentation should include a warning about the risks of LDAP filter injection. The warning should occur on pages associated with LDAP filters functionality so that it is hard for any programmer to miss. The warning maybe short (as little as one sentence), but should reference documentation that describes the risk of injections. Consider using [[LDAP injection]] or [[LDAP Injection Prevention Cheat Sheet]] as a reference. | The API documentation should include a warning about the risks of LDAP filter injection. The warning should occur on pages associated with LDAP filters functionality so that it is hard for any programmer to miss. The warning maybe short (as little as one sentence), but should reference documentation that describes the risk of injections. Consider using [[LDAP injection]] or [[LDAP Injection Prevention Cheat Sheet]] as a reference. | ||
− | == Documents LDAP Bind Authentication Without Filter Queries == | + | === Documents LDAP Bind Authentication Without Filter Queries === |
Many developers (perhaps the majority) using LDAP client libraries are trying to accomplish a simple task: authenticate users to their application by leveraging the directory server's password store. An effective way to do this can be to simply attempt an LDAP bind as the user that is trying to authenticate, using the password provided by the user. This process often does not require the use of LDAP filter expressions and avoids the risk of search filter injection. For this reason, API documentation should include a mention of this approach to help guide developers down a less error-prone path. | Many developers (perhaps the majority) using LDAP client libraries are trying to accomplish a simple task: authenticate users to their application by leveraging the directory server's password store. An effective way to do this can be to simply attempt an LDAP bind as the user that is trying to authenticate, using the password provided by the user. This process often does not require the use of LDAP filter expressions and avoids the risk of search filter injection. For this reason, API documentation should include a mention of this approach to help guide developers down a less error-prone path. | ||
− | == Provides an LDAP Filter Escape Function == | + | === Provides an LDAP Filter Escape Function === |
Escaping special characters in LDAP filter expressions is well described in section 3 of [https://tools.ietf.org/search/rfc4515 RFC 4515]. The API should provide a function which accepts a string (potentially containing LDAP filter special characters) and returns a string with the same string with any special characters appropriately escaped. For example, the string "<code>Asterisk (*) is more beautiful than backslash (\).</code>" would be converted to "<code>Asterisk \28\2a\29 is more beautiful than backslash \28\5c\29.</code>". | Escaping special characters in LDAP filter expressions is well described in section 3 of [https://tools.ietf.org/search/rfc4515 RFC 4515]. The API should provide a function which accepts a string (potentially containing LDAP filter special characters) and returns a string with the same string with any special characters appropriately escaped. For example, the string "<code>Asterisk (*) is more beautiful than backslash (\).</code>" would be converted to "<code>Asterisk \28\2a\29 is more beautiful than backslash \28\5c\29.</code>". | ||
− | == Provides LDAP Filter Syntax Templates == | + | === Provides LDAP Filter Syntax Templates === |
A "syntax template" is one way to offer an API to a developer which automatically encodes LDAP filter special characters in a safe-by-default way. Consider the pseudocode: | A "syntax template" is one way to offer an API to a developer which automatically encodes LDAP filter special characters in a safe-by-default way. Consider the pseudocode: | ||
<pre> | <pre> | ||
Line 24: | Line 24: | ||
In this hypothetical API, the developer provides a LDAP filter query template in the first argument and a list of values as the second argument. Each "<code>?</code>" that appears in the template is bound in order to the value in the list. The <code>LDAPFilterQuery</code> function is responsible for automatically encoding the values stored in <code>first_name</code> and <code>last_name</code>. Note how this is very similar to parameterized prepared statements in the realm of SQL. | In this hypothetical API, the developer provides a LDAP filter query template in the first argument and a list of values as the second argument. Each "<code>?</code>" that appears in the template is bound in order to the value in the list. The <code>LDAPFilterQuery</code> function is responsible for automatically encoding the values stored in <code>first_name</code> and <code>last_name</code>. Note how this is very similar to parameterized prepared statements in the realm of SQL. | ||
− | An LDAP API should provide either a system for filter syntax templates, or an abstract API (see next item), or both. | + | An LDAP client API should provide either a system for filter syntax templates, or an abstract API (see next item), or both. |
− | == Provides an Abstract API for LDAP Filter Queries == | + | === Provides an Abstract API for LDAP Filter Queries === |
An abstract LDAP filter API allows developers to construct a data structure or model within the caller's language which is then automatically translated by the API into a safe LDAP filter expression. Consider the pseudocode: | An abstract LDAP filter API allows developers to construct a data structure or model within the caller's language which is then automatically translated by the API into a safe LDAP filter expression. Consider the pseudocode: | ||
<pre> | <pre> | ||
Line 35: | Line 35: | ||
Note how this is somewhat similar to object-relational mappings (ORMs) in the realm of SQL. | Note how this is somewhat similar to object-relational mappings (ORMs) in the realm of SQL. | ||
− | An LDAP API should provide either an abstract API, or a filter syntax template API (see previous item), or both. | + | An LDAP client API should provide either an abstract API, or a filter syntax template API (see previous item), or both. |
− | == Supports LDAP with StartTLS == | + | === Supports LDAP with StartTLS === |
Provide support for LDAP with the StartTLS extended operation, as defined in [https://tools.ietf.org/search/rfc4513 RFC 4513]. In order to be effective (and avoid downgrade attacks), the API must provide callers with a way to '''require''' TLS be used on StartTLS connections. That is, if a developer opts for StartTLS as a communications security mechanism, then any remote server claiming that it does not support StartTLS will cause the client to close the connection without attempting a bind, search query, or any other transaction. | Provide support for LDAP with the StartTLS extended operation, as defined in [https://tools.ietf.org/search/rfc4513 RFC 4513]. In order to be effective (and avoid downgrade attacks), the API must provide callers with a way to '''require''' TLS be used on StartTLS connections. That is, if a developer opts for StartTLS as a communications security mechanism, then any remote server claiming that it does not support StartTLS will cause the client to close the connection without attempting a bind, search query, or any other transaction. | ||
− | == Supports LDAPS == | + | === Supports LDAPS === |
While not technically a standard, it is common to use LDAP over SSL/TLS on TCP port 636 (a.k.a. "LDAPS"). Often "<code>ldaps://...</code>" URLs are used to specify this and providing support for it is recommended to give developers additional deployment options. | While not technically a standard, it is common to use LDAP over SSL/TLS on TCP port 636 (a.k.a. "LDAPS"). Often "<code>ldaps://...</code>" URLs are used to specify this and providing support for it is recommended to give developers additional deployment options. | ||
− | == Enables SSL/TLS Certificate Validation by Default == | + | === Enables SSL/TLS Certificate Validation by Default === |
Whether the LDAP client library is using StartTLS or LDAPS, the client library should properly validate server certificates by default. Server certificate validation should include, at a minimum, the following two steps: | Whether the LDAP client library is using StartTLS or LDAPS, the client library should properly validate server certificates by default. Server certificate validation should include, at a minimum, the following two steps: | ||
* Validation that the server certificate is signed by a trusted certificate authority | * Validation that the server certificate is signed by a trusted certificate authority | ||
Line 50: | Line 50: | ||
Developers may be given the option of disabling one or both of these validation steps, but once again, they should be enabled by default. | Developers may be given the option of disabling one or both of these validation steps, but once again, they should be enabled by default. | ||
− | == Documents the Customization of Trusted Certificate Authorities == | + | === Documents the Customization of Trusted Certificate Authorities === |
The documentation should make it easy for developers to obtain the information they need (perhaps with links to external tutorials) in order to add a custom certificate to the list of trusted CAs that the library uses. Even if the LDAP library simply relies on the trusted CAs installed on a system-wide basis, this should be documented. It is common for internal SSL/TLS services to leverage an organization's internal certificate authority for authentication, so it is important that developers are pointed in the right direction on how to set this up client-side. | The documentation should make it easy for developers to obtain the information they need (perhaps with links to external tutorials) in order to add a custom certificate to the list of trusted CAs that the library uses. Even if the LDAP library simply relies on the trusted CAs installed on a system-wide basis, this should be documented. It is common for internal SSL/TLS services to leverage an organization's internal certificate authority for authentication, so it is important that developers are pointed in the right direction on how to set this up client-side. | ||
− | == Documents the Risk of Disabling Certificate Validation == | + | === Documents the Risk of Disabling Certificate Validation === |
The documentation should contain simple warnings indicating to developers the risk of disabling certificate validation checks. Consider using the following text, or something similar: | The documentation should contain simple warnings indicating to developers the risk of disabling certificate validation checks. Consider using the following text, or something similar: | ||
<blockquote>''Disabling certificate validation typically results in the loss of all communications security. In other words, the protections against tampering and information leakage that SSL/TLS provides are typically rendered completely ineffective when certificate validation isn't fully performed.''</blockquote> | <blockquote>''Disabling certificate validation typically results in the loss of all communications security. In other words, the protections against tampering and information leakage that SSL/TLS provides are typically rendered completely ineffective when certificate validation isn't fully performed.''</blockquote> | ||
− | = Grading | + | = Grading = |
− | + | In order to compare the relative security of LDAP client APIs on different platforms, we use the following scoring system: | |
+ | * TODO | ||
= TODO = | = TODO = |
Revision as of 16:45, 19 January 2016
This standard is designed to describe the properties that secure LDAP client APIs exhibit. APIs with these properties help developers, regardless of their skill or experience with LDAP, avoid the most common and serious vulnerabilities associated with developing LDAP client software.
Version: 0.1
Maintainer: Timothy D. Morgan
- 1 Properties of Safe LDAP Client APIs
- 1.1 Documents the Security Risks of LDAP Filter Injection
- 1.2 Documents LDAP Bind Authentication Without Filter Queries
- 1.3 Provides an LDAP Filter Escape Function
- 1.4 Provides LDAP Filter Syntax Templates
- 1.5 Provides an Abstract API for LDAP Filter Queries
- 1.6 Supports LDAP with StartTLS
- 1.7 Supports LDAPS
- 1.8 Enables SSL/TLS Certificate Validation by Default
- 1.9 Documents the Customization of Trusted Certificate Authorities
- 1.10 Documents the Risk of Disabling Certificate Validation
- 2 Grading
- 3 TODO
Properties of Safe LDAP Client APIs
Documents the Security Risks of LDAP Filter Injection
The API documentation should include a warning about the risks of LDAP filter injection. The warning should occur on pages associated with LDAP filters functionality so that it is hard for any programmer to miss. The warning maybe short (as little as one sentence), but should reference documentation that describes the risk of injections. Consider using LDAP injection or LDAP Injection Prevention Cheat Sheet as a reference.
Documents LDAP Bind Authentication Without Filter Queries
Many developers (perhaps the majority) using LDAP client libraries are trying to accomplish a simple task: authenticate users to their application by leveraging the directory server's password store. An effective way to do this can be to simply attempt an LDAP bind as the user that is trying to authenticate, using the password provided by the user. This process often does not require the use of LDAP filter expressions and avoids the risk of search filter injection. For this reason, API documentation should include a mention of this approach to help guide developers down a less error-prone path.
Provides an LDAP Filter Escape Function
Escaping special characters in LDAP filter expressions is well described in section 3 of RFC 4515. The API should provide a function which accepts a string (potentially containing LDAP filter special characters) and returns a string with the same string with any special characters appropriately escaped. For example, the string "Asterisk (*) is more beautiful than backslash (\).
" would be converted to "Asterisk \28\2a\29 is more beautiful than backslash \28\5c\29.
".
Provides LDAP Filter Syntax Templates
A "syntax template" is one way to offer an API to a developer which automatically encodes LDAP filter special characters in a safe-by-default way. Consider the pseudocode:
result = LDAPFilterQuery("(&(objectClass=user)(firstName=*?*)(lastName=*?*))", [first_name, last_name])
In this hypothetical API, the developer provides a LDAP filter query template in the first argument and a list of values as the second argument. Each "?
" that appears in the template is bound in order to the value in the list. The LDAPFilterQuery
function is responsible for automatically encoding the values stored in first_name
and last_name
. Note how this is very similar to parameterized prepared statements in the realm of SQL.
An LDAP client API should provide either a system for filter syntax templates, or an abstract API (see next item), or both.
Provides an Abstract API for LDAP Filter Queries
An abstract LDAP filter API allows developers to construct a data structure or model within the caller's language which is then automatically translated by the API into a safe LDAP filter expression. Consider the pseudocode:
result = LDAPFilterQuery(LDAPAnd({"objectClass":"user", "account":username}))
In this hypothetical API, if the username had a value "AcmeCorp\Bob
", then the LDAP filter expression generated by the API might look like: (&(objectClass=user)(account=AcmeCorp\5cBob))
Note how this is somewhat similar to object-relational mappings (ORMs) in the realm of SQL.
An LDAP client API should provide either an abstract API, or a filter syntax template API (see previous item), or both.
Supports LDAP with StartTLS
Provide support for LDAP with the StartTLS extended operation, as defined in RFC 4513. In order to be effective (and avoid downgrade attacks), the API must provide callers with a way to require TLS be used on StartTLS connections. That is, if a developer opts for StartTLS as a communications security mechanism, then any remote server claiming that it does not support StartTLS will cause the client to close the connection without attempting a bind, search query, or any other transaction.
Supports LDAPS
While not technically a standard, it is common to use LDAP over SSL/TLS on TCP port 636 (a.k.a. "LDAPS"). Often "ldaps://...
" URLs are used to specify this and providing support for it is recommended to give developers additional deployment options.
Enables SSL/TLS Certificate Validation by Default
Whether the LDAP client library is using StartTLS or LDAPS, the client library should properly validate server certificates by default. Server certificate validation should include, at a minimum, the following two steps:
- Validation that the server certificate is signed by a trusted certificate authority
- Validation that the server certificate's host name matches the host name that the developer provided
Developers may be given the option of disabling one or both of these validation steps, but once again, they should be enabled by default.
Documents the Customization of Trusted Certificate Authorities
The documentation should make it easy for developers to obtain the information they need (perhaps with links to external tutorials) in order to add a custom certificate to the list of trusted CAs that the library uses. Even if the LDAP library simply relies on the trusted CAs installed on a system-wide basis, this should be documented. It is common for internal SSL/TLS services to leverage an organization's internal certificate authority for authentication, so it is important that developers are pointed in the right direction on how to set this up client-side.
Documents the Risk of Disabling Certificate Validation
The documentation should contain simple warnings indicating to developers the risk of disabling certificate validation checks. Consider using the following text, or something similar:
Disabling certificate validation typically results in the loss of all communications security. In other words, the protections against tampering and information leakage that SSL/TLS provides are typically rendered completely ineffective when certificate validation isn't fully performed.
Grading
In order to compare the relative security of LDAP client APIs on different platforms, we use the following scoring system:
- TODO
TODO
- What other forms of encryption should we encourage? SASL and/or proprietary mechanisms?
- The LDAP injection page could use work. Some statements are a bit off base, and there should be a clearer statement of the risk.
- Review the LDAP Injection Prevention Cheat Sheet page to see if it needs work as well.