[APPSEC-801] Migrate S4433 to LaYC format. (#2307)

This commit is contained in:
gaetan-ferry-sonarsource 2023-06-29 16:45:36 +02:00 committed by GitHub
parent fe5c2e4c2f
commit 117d6b9c7e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 213 additions and 48 deletions

View File

@ -3,6 +3,10 @@
{ {
"language": "markdown", "language": "markdown",
"scheme": "file" "scheme": "file"
},
{
"language": "asciidoc",
"scheme": "file"
} }
] ]
} }

View File

@ -0,0 +1,5 @@
When configured to accept the Anonymous or Unauthenticated authentication
mechanism, an LDAP server will accept connections from clients that do not
provide a password or other authentication credentials. Such users will be
able to read or modify part or all of the data contained in the hosted
directory.

View File

@ -0,0 +1,3 @@
The following code indicates an anonymous LDAP authentication vulnerability
because it binds to a remote server using an Anonymous Simple authentication
mechanism.

View File

@ -0,0 +1,30 @@
An attacker exploiting unauthenticated access to an LDAP server can access the
data that is stored in the corresponding directory. The impact varies depending
on the permission obtained on the directory and the type of data it stores.
==== Authentication bypass
If attackers get write access to the directory, they will be able to alter
most of the data it stores. This might include sensitive technical data such as
user passwords or asset configurations. Such an attack can typically lead to
an authentication bypass on applications and systems that use the affected
directory as an identity provider.
In such a case, all users configured in the directory might see their identity
and privileges taken over.
==== Sensitive information leak
If attackers get read-only access to the directory, they will be able to read
the data it stores. That data might include security-sensitive pieces of
information.
Typically, attackers might get access to user account lists that they can use
in further intrusion steps. For example, they could use such lists to perform
password spraying, or related attacks, on all systems that rely on the affected
directory as an identity provider.
If the directory contains some Personally Identifiable Information, an attacker
accessing it might represent a violation of regulatory requirements in some
countries. For example, this kind of security event would go against the
European GDPR law.

View File

@ -0,0 +1,10 @@
Lightweight Directory Access Protocol (LDAP) servers provide two main
authentication methods: the _SASL_ and _Simple_ ones. The _Simple
Authentication_ method also breaks down into three different mechanisms:
* _Anonymous_ Authentication
* _Unauthenticated_ Authentication
* _Name/Password_ Authentication
A server that accepts either the _Anonymous_ or _Unauthenticated_ mechanisms will
accept connections from clients not providing credentials.

View File

@ -0,0 +1,3 @@
=== Documentation
* https://datatracker.ietf.org/doc/html/rfc4513#section-5[RFC 4513 - Lightweight Directory Access Protocol (LDAP): Authentication Methods and Security Mechanisms] - Bind operations

View File

@ -1,6 +1,5 @@
== Resources === Standards
* https://owasp.org/Top10/A07_2021-Identification_and_Authentication_Failures/[OWASP Top 10 2021 Category A7] - Identification and Authentication Failures * https://owasp.org/Top10/A07_2021-Identification_and_Authentication_Failures/[OWASP Top 10 2021 Category A7] - Identification and Authentication Failures
* https://owasp.org/www-project-top-ten/2017/A2_2017-Broken_Authentication[OWASP Top 10 2017 Category A2] - Broken Authentication * https://owasp.org/www-project-top-ten/2017/A2_2017-Broken_Authentication[OWASP Top 10 2017 Category A2] - Broken Authentication
* https://cwe.mitre.org/data/definitions/521[MITRE, CWE-521] - Weak Password Requirements * https://cwe.mitre.org/data/definitions/521[MITRE, CWE-521] - Weak Password Requirements
* https://web.archive.org/web/20220922153922/https://ldapwiki.com/wiki/Simple%20Authentication[ldapwiki.com]- Simple Authentication

View File

@ -1,12 +1,22 @@
include::../common/rationale.adoc[]
== Why is this an issue? == Why is this an issue?
include::../description.adoc[] include::../common/description.adoc[]
=== Noncompliant code example === What is the potential impact?
This rule raises an issue when an LDAP connection is created with ``++AuthenticationTypes.Anonymous++`` or ``++AuthenticationTypes.None++``. include::../common/impact.adoc[]
[source,csharp] == How to fix it
=== Code examples
include::../common/fix/code-rationale.adoc[]
==== Noncompliant code example
[source,csharp,diff-id=1,diff-type=noncompliant]
---- ----
DirectoryEntry myDirectoryEntry = new DirectoryEntry(adPath); DirectoryEntry myDirectoryEntry = new DirectoryEntry(adPath);
myDirectoryEntry.AuthenticationType = AuthenticationTypes.None; // Noncompliant myDirectoryEntry.AuthenticationType = AuthenticationTypes.None; // Noncompliant
@ -14,16 +24,35 @@ myDirectoryEntry.AuthenticationType = AuthenticationTypes.None; // Noncompliant
DirectoryEntry myDirectoryEntry = new DirectoryEntry(adPath, "u", "p", AuthenticationTypes.None); // Noncompliant DirectoryEntry myDirectoryEntry = new DirectoryEntry(adPath, "u", "p", AuthenticationTypes.None); // Noncompliant
---- ----
=== Compliant solution
[source,csharp] ==== Compliant solution
[source,csharp,diff-id=1,diff-type=compliant]
---- ----
DirectoryEntry myDirectoryEntry = new DirectoryEntry(myADSPath); // Compliant; default DirectoryEntry.AuthenticationType property value is "Secure" since .NET Framework 2.0 DirectoryEntry myDirectoryEntry = new DirectoryEntry(myADSPath); // Compliant; default DirectoryEntry.AuthenticationType property value is "Secure" since .NET Framework 2.0
DirectoryEntry myDirectoryEntry = new DirectoryEntry(myADSPath, "u", "p", AuthenticationTypes.Secure); DirectoryEntry myDirectoryEntry = new DirectoryEntry(myADSPath, "u", "p", AuthenticationTypes.Secure);
---- ----
include::../see.adoc[] //=== How does this work?
//=== Pitfalls
//=== Going the extra mile
== Resources
//=== Documentation
include::../common/resources/documentation.adoc[]
//=== Articles & blog posts
//=== Conference presentations
//=== Standards
include::../common/resources/standards.adoc[]
//=== Benchmarks
ifdef::env-github,rspecator-view[] ifdef::env-github,rspecator-view[]
@ -42,4 +71,4 @@ include::../highlighting.adoc[]
=== on 5 Apr 2018, 12:10:55 Alexandre Gigleux wrote: === on 5 Apr 2018, 12:10:55 Alexandre Gigleux wrote:
https://docs.microsoft.com/en-us/dotnet/api/system.directoryservices.directoryentry.authenticationtype?view=netcore-2.0#System_DirectoryServices_DirectoryEntry_AuthenticationType https://docs.microsoft.com/en-us/dotnet/api/system.directoryservices.directoryentry.authenticationtype?view=netcore-2.0#System_DirectoryServices_DirectoryEntry_AuthenticationType
endif::env-github,rspecator-view[] endif::env-github,rspecator-view[]

View File

@ -1,9 +0,0 @@
An LDAP client authenticates to an LDAP server with a "bind request" which provides, among other, a https://web.archive.org/web/20220922153922/https://ldapwiki.com/wiki/Simple%20Authentication[simple authentication method].
Simple authentication in LDAP can be used with three different mechanisms:
* _Anonymous Authentication Mechanism_ by performing a bind request with a username and password value of zero length.
* _Unauthenticated Authentication Mechanism_ by performing a bind request with a password value of zero length.
* _Name/Password Authentication Mechanism_ by performing a bind request with a password value of non-zero length.
Anonymous binds and unauthenticated binds allow access to information in the LDAP directory without providing a password, their use is therefore strongly discouraged.

View File

@ -1,12 +1,22 @@
include::../common/rationale.adoc[]
== Why is this an issue? == Why is this an issue?
include::../description.adoc[] include::../common/description.adoc[]
=== Noncompliant code example === What is the potential impact?
This rule raises an issue when an LDAP connection is created with ``++Context.SECURITY_AUTHENTICATION++`` set to ``++"none"++``. include::../common/impact.adoc[]
[source,java] == How to fix it
=== Code examples
include::../common/fix/code-rationale.adoc[]
==== Noncompliant code example
[source,java,diff-id=1,diff-type=noncompliant]
---- ----
// Set up the environment for creating the initial context // Set up the environment for creating the initial context
Hashtable<String, Object> env = new Hashtable<String, Object>(); Hashtable<String, Object> env = new Hashtable<String, Object>();
@ -20,25 +30,44 @@ env.put(Context.SECURITY_AUTHENTICATION, "none"); // Noncompliant
DirContext ctx = new InitialDirContext(env); DirContext ctx = new InitialDirContext(env);
---- ----
=== Compliant solution
[source,java] ==== Compliant solution
[source,java,diff-id=1,diff-type=compliant]
---- ----
// Set up the environment for creating the initial context // Set up the environment for creating the initial context
Hashtable<String, Object> env = new Hashtable<String, Object>(); Hashtable<String, Object> env = new Hashtable<String, Object>();
env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory"); env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
env.put(Context.PROVIDER_URL, "ldap://localhost:389/o=JNDITutorial"); env.put(Context.PROVIDER_URL, "ldap://localhost:389/o=Example");
// Use simple authentication // Use simple authentication
env.put(Context.SECURITY_AUTHENTICATION, "simple"); env.put(Context.SECURITY_AUTHENTICATION, "simple");
env.put(Context.SECURITY_PRINCIPAL, "cn=S. User, ou=NewHires, o=JNDITutorial"); env.put(Context.SECURITY_PRINCIPAL, "cn=local, ou=Unit, o=Example");
env.put(Context.SECURITY_CREDENTIALS, getLDAPPassword()); env.put(Context.SECURITY_CREDENTIALS, getLDAPPassword());
// Create the initial context // Create the initial context
DirContext ctx = new InitialDirContext(env); DirContext ctx = new InitialDirContext(env);
---- ----
include::../see.adoc[] //=== How does this work?
//=== Pitfalls
//=== Going the extra mile
== Resources
//=== Documentation
include::../common/resources/documentation.adoc[]
//=== Articles & blog posts
//=== Conference presentations
//=== Standards
include::../common/resources/standards.adoc[]
//=== Benchmarks
ifdef::env-github,rspecator-view[] ifdef::env-github,rspecator-view[]
@ -50,4 +79,4 @@ include::../message.adoc[]
include::../highlighting.adoc[] include::../highlighting.adoc[]
endif::env-github,rspecator-view[] endif::env-github,rspecator-view[]

View File

@ -1,21 +1,34 @@
include::../common/rationale.adoc[]
== Why is this an issue? == Why is this an issue?
include::../description.adoc[] include::../common/description.adoc[]
=== Noncompliant code example === What is the potential impact?
[source,php] include::../common/impact.adoc[]
== How to fix it
=== Code examples
include::../common/fix/code-rationale.adoc[]
==== Noncompliant code example
[source,php,diff-id=1,diff-type=noncompliant]
---- ----
$ldapconn = ldap_connect("ldap.example.com"); $ldapconn = ldap_connect("ldap.example.com");
if ($ldapconn) { if ($ldapconn) {
$ldapbind = ldap_bind($ldapconn); // Noncompliant; anonymous authentication, no user/password provided $ldapbind = ldap_bind($ldapconn); // Noncompliant
} }
---- ----
=== Compliant solution
[source,php] ==== Compliant solution
[source,php,diff-id=1,diff-type=compliant]
---- ----
$ldaprdn = 'uname'; $ldaprdn = 'uname';
$ldappass = 'password'; $ldappass = 'password';
@ -27,7 +40,25 @@ if ($ldapconn) {
} }
---- ----
include::../see.adoc[] //=== How does this work?
//=== Pitfalls
//=== Going the extra mile
== Resources
//=== Documentation
include::../common/resources/documentation.adoc[]
//=== Articles & blog posts
//=== Conference presentations
//=== Standards
include::../common/resources/standards.adoc[]
//=== Benchmarks
ifdef::env-github,rspecator-view[] ifdef::env-github,rspecator-view[]
@ -42,4 +73,4 @@ Provide username and password to authenticate the connection.
include::../highlighting.adoc[] include::../highlighting.adoc[]
endif::env-github,rspecator-view[] endif::env-github,rspecator-view[]

View File

@ -1,10 +1,22 @@
include::../common/rationale.adoc[]
== Why is this an issue? == Why is this an issue?
include::../description.adoc[] include::../common/description.adoc[]
=== Noncompliant code example === What is the potential impact?
[source,python] include::../common/impact.adoc[]
== How to fix it
=== Code examples
include::../common/fix/code-rationale.adoc[]
==== Noncompliant code example
[source,python,diff-id=1,diff-type=noncompliant]
---- ----
import ldap import ldap
@ -17,9 +29,10 @@ def init_ldap():
connect.bind('cn=root', None) # Noncompliant connect.bind('cn=root', None) # Noncompliant
---- ----
=== Compliant solution
[source,python] ==== Compliant solution
[source,python,diff-id=1,diff-type=compliant]
---- ----
import ldap import ldap
import os import os
@ -27,13 +40,31 @@ import os
def init_ldap(): def init_ldap():
connect = ldap.initialize('ldap://example:1389') connect = ldap.initialize('ldap://example:1389')
connect.simple_bind('cn=root', os.environ.get('LDAP_PASSWORD')) # Compliant connect.simple_bind('cn=root', os.environ.get('LDAP_PASSWORD'))
connect.simple_bind_s('cn=root', os.environ.get('LDAP_PASSWORD')) # Compliant connect.simple_bind_s('cn=root', os.environ.get('LDAP_PASSWORD'))
connect.bind_s('cn=root', os.environ.get('LDAP_PASSWORD')) # Compliant connect.bind_s('cn=root', os.environ.get('LDAP_PASSWORD'))
connect.bind('cn=root', os.environ.get('LDAP_PASSWORD')) # Compliant connect.bind('cn=root', os.environ.get('LDAP_PASSWORD'))
---- ----
include::../see.adoc[] //=== How does this work?
//=== Pitfalls
//=== Going the extra mile
== Resources
//=== Documentation
include::../common/resources/documentation.adoc[]
//=== Articles & blog posts
//=== Conference presentations
//=== Standards
include::../common/resources/standards.adoc[]
//=== Benchmarks
ifdef::env-github,rspecator-view[] ifdef::env-github,rspecator-view[]