diff --git a/docs/header_names/allowed_framework_names.adoc b/docs/header_names/allowed_framework_names.adoc index d43ae33023..dcf13d82fb 100644 --- a/docs/header_names/allowed_framework_names.adoc +++ b/docs/header_names/allowed_framework_names.adoc @@ -18,6 +18,10 @@ * NSubstitute * MSTest * NUnit +// C-family +* cURL +* Botan +* OpenSSL // Java * Apache Commons * JSP @@ -33,6 +37,7 @@ * Gson * Android * Java Cryptographic Extension +* OkHttp // JS * Node.js * Express.js @@ -71,6 +76,20 @@ * pyca * PyCrypto * pyDes +// Docker +* Wget +// Cloudformation +* API Gateway +* OpenSearch +// Azure Resource Manager +* Storage Accounts +* Databases +// Terraform +* AWS API Gateway +* AWS OpenSearch +// CDK +* AWS CDK +* GCP Load Balancers // Swift * CommonCrypto * CryptoSwift diff --git a/rules/S4423/apex/metadata.json b/rules/S4423/apex/metadata.json deleted file mode 100644 index 1797133380..0000000000 --- a/rules/S4423/apex/metadata.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - -} diff --git a/rules/S4423/apex/rule.adoc b/rules/S4423/apex/rule.adoc deleted file mode 100644 index f5db9e87ac..0000000000 --- a/rules/S4423/apex/rule.adoc +++ /dev/null @@ -1,18 +0,0 @@ -include::../rule.adoc[] - -ifdef::env-github,rspecator-view[] - -''' -== Implementation Specification -(visible only on this page) - -include::../message.adoc[] - -include::../highlighting.adoc[] - -''' -== Comments And Links -(visible only on this page) - -include::../comments-and-links.adoc[] -endif::env-github,rspecator-view[] diff --git a/rules/S4423/azureresourcemanager/how-to-fix-it/azure-mysql.adoc b/rules/S4423/azureresourcemanager/how-to-fix-it/azure-mysql.adoc new file mode 100644 index 0000000000..ad459ae1da --- /dev/null +++ b/rules/S4423/azureresourcemanager/how-to-fix-it/azure-mysql.adoc @@ -0,0 +1,54 @@ +== How to fix it in Databases + +=== Code examples + +The following code samples are equivalent For +https://learn.microsoft.com/en-us/azure/templates/microsoft.dbformysql/servers[Azure Database for MySQL servers], +https://learn.microsoft.com/en-us/azure/templates/microsoft.dbforpostgresql/servers[Azure Database for PostgreSQL servers], +and https://learn.microsoft.com/en-us/azure/templates/microsoft.dbformariadb/servers[Azure Database for MariaDB servers]. + +For all of these, there is no minimal TLS version enforced by default. + +==== Noncompliant code example + +[source,json,diff-id=1,diff-type=noncompliant] +---- +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [ + { + "type": "Microsoft.DBforMySQL/servers", + "apiVersion": "2017-12-01", + "name": "example", + "properties": { + "minimalTlsVersion": "TLS1_0" + } + } + ] +} +---- + +==== Compliant solution + +[source,json,diff-id=1,diff-type=compliant] +---- +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [ + { + "type": "Microsoft.DBforMySQL/servers", + "apiVersion": "2017-12-01", + "name": "example", + "properties": { + "minimalTlsVersion": "TLS1_2" + } + } + ] +} +---- + +=== How does this work? + +include::../../common/fix/fix.adoc[] diff --git a/rules/S4423/azureresourcemanager/how-to-fix-it/azure-storage-account.adoc b/rules/S4423/azureresourcemanager/how-to-fix-it/azure-storage-account.adoc new file mode 100644 index 0000000000..6b56df25fc --- /dev/null +++ b/rules/S4423/azureresourcemanager/how-to-fix-it/azure-storage-account.adoc @@ -0,0 +1,51 @@ + +== How to fix it in Storage Accounts + +=== Code examples + +==== Noncompliant code example + +On Storage Accounts, TLS 1.0 and 1.1 are accepted by default. + +[source,json,diff-id=2,diff-type=noncompliant] +---- +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [ + { + "type": "Microsoft.Storage/storageAccounts", + "apiVersion": "2022-09-01", + "name": "example", + "properties": { + "minimumTlsVersion": "TLS1_0" + } + } + ] +} +---- + +==== Compliant solution + +[source,json,diff-id=1,diff-type=compliant] +---- +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [ + { + "type": "Microsoft.Storage/storageAccounts", + "apiVersion": "2022-09-01", + "name": "example", + "properties": { + "minimumTlsVersion": "TLS1_2" + } + } + ] +} +---- + +=== How does this work? + +include::../../common/fix/fix.adoc[] + diff --git a/rules/S4423/azureresourcemanager/rule.adoc b/rules/S4423/azureresourcemanager/rule.adoc index 3f1c1cbcf5..21c6de795f 100644 --- a/rules/S4423/azureresourcemanager/rule.adoc +++ b/rules/S4423/azureresourcemanager/rule.adoc @@ -1,94 +1,26 @@ +include::../summary.adoc[] + == Why is this an issue? -include::../description.adoc[] +include::../rationale.adoc[] -=== Noncompliant code example +include::../impact.adoc[] -For https://learn.microsoft.com/en-us/azure/templates/microsoft.storage/storageaccounts[Azure Storage accounts], TLS 1.0 and 1.1 are accepted by default. +// How to fix it section +include::how-to-fix-it/azure-mysql.adoc[] -[source,json,diff-id=2,diff-type=noncompliant] ----- -{ - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "resources": [ - { - "type": "Microsoft.Storage/storageAccounts", - "apiVersion": "2022-09-01", - "name": "example", - "properties": { - "minimumTlsVersion": "TLS1_0" - } - } - ] -} ----- +include::how-to-fix-it/azure-storage-account.adoc[] -For https://learn.microsoft.com/en-us/azure/templates/microsoft.dbformysql/servers[Azure Database for MySQL servers], https://learn.microsoft.com/en-us/azure/templates/microsoft.dbforpostgresql/servers[Azure Database for PostgreSQL servers], and https://learn.microsoft.com/en-us/azure/templates/microsoft.dbformariadb/servers[Azure Database for MariaDB servers], there is no minimal TLS version enforced by default. +== Resources -[source,json,diff-id=4,diff-type=noncompliant] ----- -{ - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "resources": [ - { - "type": "Microsoft.DBforMySQL/servers", - "apiVersion": "2017-12-01", - "name": "example", - "properties": { - "minimalTlsVersion": "TLS1_0" - } - } - ] -} ----- +include::../common/resources/docs.adoc[] -== Compliant Solution +include::../common/resources/articles.adoc[] -For https://learn.microsoft.com/en-us/azure/templates/microsoft.storage/storageaccounts[Azure Storage accounts]: +include::../common/resources/presentations.adoc[] -[source,json,diff-id=2,diff-type=compliant] ----- -{ - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "resources": [ - { - "type": "Microsoft.Storage/storageAccounts", - "apiVersion": "2022-09-01", - "name": "example", - "properties": { - "minimumTlsVersion": "TLS1_2" - } - } - ] -} ----- +include::../common/resources/standards.adoc[] -For https://learn.microsoft.com/en-us/azure/templates/microsoft.dbformysql/servers[Azure Database for MySQL servers], https://learn.microsoft.com/en-us/azure/templates/microsoft.dbforpostgresql/servers[Azure Database for PostgreSQL servers], and https://learn.microsoft.com/en-us/azure/templates/microsoft.dbformariadb/servers[Azure Database for MariaDB servers]: - -[source,json,diff-id=4,diff-type=compliant] ----- -{ - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "resources": [ - { - "type": "Microsoft.DBforMySQL/servers", - "apiVersion": "2017-12-01", - "name": "example", - "properties": { - "minimalTlsVersion": "TLS1_2" - } - } - ] -} ----- - -include::../see.adoc[] - -* https://learn.microsoft.com/en-us/azure/azure-sql/database/connectivity-settings#minimal-tls-version[Microsoft Learn] - Azure SQL - Minimal TLS version ifdef::env-github,rspecator-view[] @@ -96,12 +28,14 @@ ifdef::env-github,rspecator-view[] == Implementation Specification (visible only on this page) +=== Message + * If `minimumTlsVersion`/`minimalTlsVersion` is specified but has the wrong value ** Change this code to disable support of older TLS versions. - * If `minimumTlsVersion`/`minimalTlsVersion` is not specified at all ** Set `minimumTlsVersion`/`minimalTlsVersion` to disable support of older TLS versions. +=== Highlighting * Highlight `minimumTlsVersion`/`minimalTlsVersion` if it is specified but has the wrong value * Highlight resource if `minimumTlsVersion`/`minimalTlsVersion` is not specified at all diff --git a/rules/S4423/cfamily/how-to-fix-it/botan.adoc b/rules/S4423/cfamily/how-to-fix-it/botan.adoc new file mode 100644 index 0000000000..f9b44d0c0b --- /dev/null +++ b/rules/S4423/cfamily/how-to-fix-it/botan.adoc @@ -0,0 +1,71 @@ +== How to fix it in Botan + +=== Code examples + +The following code samples attempt to create a Botan TLS Client. + +==== Noncompliant code example + +This sample uses Botan's default TLS algorithms, which are weak cryptographical +algorithms (TLSv1.0 and DLTv1.0). + +[source,cpp,diff-id=1,diff-type=noncompliant] +---- +#include +#include +#include +#include +#include +#include +#include + +class Custom_Callbacks : public Botan::TLS::Callbacks { }; +class Custom_Credentials : public Botan::Credentials_Manager { }; + +void encrypt() { + Custom_Callbacks callbacks; + Botan::AutoSeeded_RNG rng; + Custom_Credentials creds; + Botan::TLS::Policy policy; // Noncompliant + + Botan::TLS::Session_Manager_In_Memory session_mgr(rng); + Botan::TLS::Client client(callbacks, session_mgr, creds, policy, rng, + Botan::TLS::Server_Information("example.com", 443), + Botan::TLS::Protocol_Version::TLS_V12); +} +---- + +==== Compliant solution + +This sample uses the "Strict" Botan TLS Policy, whose minimal versions are +strong cryptographical algorithms (TLSv1.2 and TLSv1.2). + +[source,cpp,diff-id=1,diff-type=compliant] +---- +#include +#include +#include +#include +#include +#include +#include + +class Custom_Callbacks : public Botan::TLS::Callbacks { }; +class Custom_Credentials : public Botan::Credentials_Manager { }; + +void encrypt() { + Custom_Callbacks callbacks; + Botan::AutoSeeded_RNG rng; + Custom_Credentials creds; + Botan::TLS::Strict_Policy policy; + + Botan::TLS::Session_Manager_In_Memory session_mgr(rng); + Botan::TLS::Client client(callbacks, session_mgr, creds, policy, rng, + Botan::TLS::Server_Information("example.com", 443), + Botan::TLS::Protocol_Version::TLS_V12); +} +---- + +=== How does this work? + +include::../../common/fix/fix.adoc[] diff --git a/rules/S4423/cfamily/how-to-fix-it/curl.adoc b/rules/S4423/cfamily/how-to-fix-it/curl.adoc new file mode 100644 index 0000000000..ae17a6aece --- /dev/null +++ b/rules/S4423/cfamily/how-to-fix-it/curl.adoc @@ -0,0 +1,47 @@ +== How to fix it in cURL + +=== Code examples + +The following code samples attempt to create an HTTP request. + +==== Noncompliant code example + +This sample uses Curl's default TLS algorithms, which are weak +cryptographical algorithms: TLSv1.0 and LTSv1.1. + +[source,cpp,diff-id=1,diff-type=noncompliant] +---- +#include + +void encrypt() { + CURL *curl; + curl_global_init(CURL_GLOBAL_DEFAULT); + + curl = curl_easy_init(); // Noncompliant + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/"); + + curl_easy_perform(curl); +} +---- + +==== Compliant solution + +[source,cpp,diff-id=1,diff-type=compliant] +---- +#include + +void encrypt() { + CURL *curl; + curl_global_init(CURL_GLOBAL_DEFAULT); + + curl = curl_easy_init(); + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/"); + curl_easy_setopt(curl, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1_2); + + curl_easy_perform(curl); +} +---- + +=== How does this work? + +include::../../common/fix/fix.adoc[] diff --git a/rules/S4423/cfamily/how-to-fix-it/openssl.adoc b/rules/S4423/cfamily/how-to-fix-it/openssl.adoc new file mode 100644 index 0000000000..12a63ae4d5 --- /dev/null +++ b/rules/S4423/cfamily/how-to-fix-it/openssl.adoc @@ -0,0 +1,45 @@ + +== How to fix it in OpenSSL + +=== Code examples + +The following code samples attempt to create an OpenSSL TLS Client. + +==== Noncompliant code example + +This sample uses OpenSSL's default TLS algorithms, which are weak +cryptographical algorithms (TLSv1.0 and LTSv1.1). + +[source,cpp,diff-id=1,diff-type=noncompliant] +---- +#include + +void encrypt() { + const SSL_METHOD *method = TLS_method(); // Noncompliant + SSL_CTX *ctx = SSL_CTX_new(method); + + SSL *ssl = SSL_new(ctx); + SSL_connect(ssl); +} +---- + +==== Compliant solution + +[source,cpp,diff-id=1,diff-type=compliant] +---- +#include + +void encrypt() { + const SSL_METHOD *method = TLS_method(); + SSL_CTX *ctx = SSL_CTX_new(method); + + SSL_CTX_set_min_proto_version(ctx, TLS1_2_VERSION); + + SSL *ssl = SSL_new(ctx); + SSL_connect(ssl); +} +---- + +=== How does this work? + +include::../../common/fix/fix.adoc[] diff --git a/rules/S4423/cfamily/rule.adoc b/rules/S4423/cfamily/rule.adoc index 6ec705aaab..3437dc9093 100644 --- a/rules/S4423/cfamily/rule.adoc +++ b/rules/S4423/cfamily/rule.adoc @@ -1,166 +1,28 @@ +include::../summary.adoc[] + == Why is this an issue? -include::../description.adoc[] +include::../rationale.adoc[] -=== Noncompliant code example +include::../impact.adoc[] -https://github.com/curl/curl[libcurl] +// How to fix it section +include::how-to-fix-it/curl.adoc[] -[source,cpp] ----- -#include +include::how-to-fix-it/openssl.adoc[] -CURL *curl; -curl_global_init(CURL_GLOBAL_DEFAULT); +include::how-to-fix-it/botan.adoc[] -// CURL_SSLVERSION_DEFAULT is the default option for CURLOPT_SSLVERSION -// It means legacy version TLSv1 and TLSv1.1 are enabled -curl = curl_easy_init(); // Noncompliant -curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/"); +== Resources -// Perform the request -curl_easy_perform(curl); ----- +include::../common/resources/docs.adoc[] -[source,cpp] ----- -#include +include::../common/resources/articles.adoc[] -CURL *curl; -curl_global_init(CURL_GLOBAL_DEFAULT); +include::../common/resources/presentations.adoc[] -curl = curl_easy_init(); -curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/"); +include::../common/resources/standards.adoc[] -curl_easy_setopt(curl, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1); // Noncompliant; legacy version TLSv1 and TLSv1.1 are enabled - -//Perform the request -curl_easy_perform(curl); ----- - -https://github.com/openssl/openssl[OpenSSL] - -[source,cpp] ----- -#include - -const SSL_METHOD *method = TLS_method(); // Noncompliant; legacy version TLSv1 and TLSv1.1 are enabled -SSL_CTX *ctx = SSL_CTX_new(method); - -SSL *ssl = SSL_new(ctx); - -// ... - -SSL_connect(ssl); ----- - -https://github.com/randombit/botan[botan] - -[source,cpp] ----- -#include -#include -#include -#include -#include -#include -#include - -class Callbacks : public Botan::TLS::Callbacks -{ -// ... -}; - -class Client_Credentials : public Botan::Credentials_Manager -{ -// ... -}; - -Callbacks callbacks; -Botan::AutoSeeded_RNG rng; -Botan::TLS::Session_Manager_In_Memory session_mgr(rng); -Client_Credentials creds; -Botan::TLS::Policy policy; // Noncompliant: Default Policy has TLSv1.0 and DLTv1.0 as minimal versions - -// open the tls connection -Botan::TLS::Client client(callbacks, session_mgr, creds, policy, rng, - Botan::TLS::Server_Information("example.com", 443), - Botan::TLS::Protocol_Version::TLS_V12); ----- - -=== Compliant solution - -https://github.com/curl/curl[libcurl] - -[source,cpp] ----- -#include - -CURL *curl; -curl_global_init(CURL_GLOBAL_DEFAULT); - -curl = curl_easy_init(); -curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/"); - -curl_easy_setopt(curl, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1_2); // Compliant; enables TLSv1.2 / TLSv1.3 version only - -// Perform the request -curl_easy_perform(curl); ----- - -https://github.com/openssl/openssl[OpenSSL] - -[source,cpp] ----- -#include - -const SSL_METHOD *method = TLS_method(); - -SSL_CTX *ctx = SSL_CTX_new(method); -SSL_CTX_set_min_proto_version(ctx, TLS1_2_VERSION); // Compliant; enables TLSv1.2 / TLSv1.3 version only - -SSL *ssl = SSL_new(ctx); - -// ... - -SSL_connect(ssl); ----- - -https://github.com/randombit/botan[botan] - -[source,cpp] ----- -#include -#include -#include -#include -#include -#include -#include - -class Callbacks : public Botan::TLS::Callbacks -{ -// ... -}; - -class Client_Credentials : public Botan::Credentials_Manager -{ -// ... -}; - -Callbacks callbacks; -Botan::AutoSeeded_RNG rng; -Botan::TLS::Session_Manager_In_Memory session_mgr(rng); -Client_Credentials creds; -Botan::TLS::Strict_Policy policy; // Compliant: Strict_Policy has TLSv1.2 and TLSv1.2 as minimal versions - -// open the tls connection -Botan::TLS::Client client(callbacks, session_mgr, creds, policy, rng, - Botan::TLS::Server_Information("example.com", 443), - Botan::TLS::Protocol_Version::TLS_V12); ----- - -include::../see.adoc[] ifdef::env-github,rspecator-view[] @@ -170,8 +32,6 @@ ifdef::env-github,rspecator-view[] include::../message.adoc[] -include::../highlighting.adoc[] - ''' == Comments And Links (visible only on this page) diff --git a/rules/S4423/cloudformation/how-to-fix-it/api-gateway.adoc b/rules/S4423/cloudformation/how-to-fix-it/api-gateway.adoc new file mode 100644 index 0000000000..ca0cc318d9 --- /dev/null +++ b/rules/S4423/cloudformation/how-to-fix-it/api-gateway.adoc @@ -0,0 +1,55 @@ +== How to fix it in API Gateway + +=== Code examples + +These code samples illustrate how to fix this issue in both APIGateway and +ApiGatewayV2. + +==== Noncompliant code example + +[source,cloudformation,diff-id=1,diff-type=noncompliant] +---- +AWSTemplateFormatVersion: '2010-09-09' +Resources: + CustomApi: + Type: AWS::ApiGateway::DomainName + Properties: + SecurityPolicy: "TLS_1_0" # Noncompliant +---- + +The ApiGatewayV2 uses a weak TLS version by default: + +[source,cloudformation,diff-id=2,diff-type=noncompliant] +---- +AWSTemplateFormatVersion: '2010-09-09' +Resources: + CustomApi: # Noncompliant + Type: AWS::ApiGatewayV2::DomainName +---- + +==== Compliant solution + +[source,cloudformation,diff-id=1,diff-type=compliant] +---- +AWSTemplateFormatVersion: '2010-09-09' +Resources: + CustomApi: + Type: AWS::ApiGateway::DomainName + Properties: + SecurityPolicy: "TLS_1_2" +---- + +[source,cloudformation,diff-id=2,diff-type=compliant] +---- +AWSTemplateFormatVersion: '2010-09-09' +Resources: + CustomApi: + Type: AWS::ApiGatewayV2::DomainName + Properties: + DomainNameConfigurations: + - SecurityPolicy: "TLS_1_2" +---- + +=== How does this work? + +include::../../common/fix/fix.adoc[] diff --git a/rules/S4423/cloudformation/how-to-fix-it/opensearch.adoc b/rules/S4423/cloudformation/how-to-fix-it/opensearch.adoc new file mode 100644 index 0000000000..9db341ae83 --- /dev/null +++ b/rules/S4423/cloudformation/how-to-fix-it/opensearch.adoc @@ -0,0 +1,38 @@ +== How to fix it in OpenSearch + +=== Code examples + +==== Noncompliant code example + +[source,cloudformation,diff-id=1,diff-type=noncompliant] +---- +AWSTemplateFormatVersion: 2010-09-09 +Resources: + Example: + Type: AWS::OpenSearchService::Domain + Properties: + DomainName: example + DomainEndpointOptions: + EnforceHTTPS: true + TLSSecurityPolicy: "Policy-Min-TLS-1-0-2019-07" # Noncompliant +---- + +==== Compliant solution + +[source,cloudformation,diff-id=1,diff-type=compliant] +---- +AWSTemplateFormatVersion: 2010-09-09 +Resources: + Example: + Type: AWS::OpenSearchService::Domain + Properties: + DomainName: example + DomainEndpointOptions: + EnforceHTTPS: true + TLSSecurityPolicy: "Policy-Min-TLS-1-2-2019-07" +---- + +=== How does this work? + +include::../../common/fix/fix.adoc[] + diff --git a/rules/S4423/cloudformation/rule.adoc b/rules/S4423/cloudformation/rule.adoc index 8bccf4727b..eb1ed34175 100644 --- a/rules/S4423/cloudformation/rule.adoc +++ b/rules/S4423/cloudformation/rule.adoc @@ -1,87 +1,25 @@ +include::../summary.adoc[] + == Why is this an issue? -include::../description.adoc[] +include::../rationale.adoc[] -=== Noncompliant code example +include::../impact.adoc[] -For https://docs.aws.amazon.com/opensearch-service/index.html[Amazon OpenSearch domains]: +// How to fix it section +include::how-to-fix-it/api-gateway.adoc[] -[source,yaml] ----- -AWSTemplateFormatVersion: 2010-09-09 -Resources: - Example: - Type: AWS::OpenSearchService::Domain - Properties: - DomainName: example - DomainEndpointOptions: - EnforceHTTPS: true - TLSSecurityPolicy: "Policy-Min-TLS-1-0-2019-07" # Noncompliant ----- +include::how-to-fix-it/opensearch.adoc[] -For https://aws.amazon.com/api-gateway/[Amazon API Gateway]: +== Resources -[source,yaml] ----- -AWSTemplateFormatVersion: '2010-09-09' -Resources: - CustomApi: - Type: AWS::ApiGateway::DomainName - Properties: - SecurityPolicy: "TLS_1_0" # Noncompliant ----- +include::../common/resources/docs.adoc[] -[source,yaml] ----- -AWSTemplateFormatVersion: '2010-09-09' -Resources: - CustomApi: # Noncompliant - Type: AWS::ApiGatewayV2::DomainName ----- +include::../common/resources/articles.adoc[] -=== Compliant solution - -For https://docs.aws.amazon.com/opensearch-service/index.html[Amazon OpenSearch domains]: - -[source,yaml] ----- -AWSTemplateFormatVersion: 2010-09-09 -Resources: - Example: - Type: AWS::OpenSearchService::Domain - Properties: - DomainName: example - DomainEndpointOptions: - EnforceHTTPS: true - TLSSecurityPolicy: "Policy-Min-TLS-1-2-2019-07" ----- - -For https://aws.amazon.com/api-gateway/[Amazon API Gateway]: - -[source,yaml] ----- -AWSTemplateFormatVersion: '2010-09-09' -Resources: - CustomApi: - Type: AWS::ApiGateway::DomainName - Properties: - SecurityPolicy: "TLS_1_2" ----- - -[source,yaml] ----- -AWSTemplateFormatVersion: '2010-09-09' -Resources: - CustomApi: - Type: AWS::ApiGatewayV2::DomainName - Properties: - DomainNameConfigurations: - - SecurityPolicy: "TLS_1_2" ----- - -include::../see.adoc[] -* https://docs.aws.amazon.com/apigateway/latest/developerguide/apigateway-custom-domain-tls-version.html[Amazon API Gateway] - Choosing a minimum TLS version +include::../common/resources/presentations.adoc[] +include::../common/resources/standards.adoc[] ifdef::env-github,rspecator-view[] @@ -139,6 +77,7 @@ For `AWS::ApiGatewayV2::DomainName`: * Highlight resource if `DomainNameConfigurations` does not exist + ''' == Comments And Links (visible only on this page) diff --git a/rules/S4423/common/fix/fix.adoc b/rules/S4423/common/fix/fix.adoc new file mode 100644 index 0000000000..517dd4d5cb --- /dev/null +++ b/rules/S4423/common/fix/fix.adoc @@ -0,0 +1,21 @@ +As a rule of thumb, by default you should use the cryptographic algorithms and +mechanisms that are considered strong by the cryptographic community. + +The best choices at the moment are the following. + +==== Use TLS v1.2 or TLS v1.3 +Even though TLS V1.3 is available, using TLS v1.2 is still considered good and +secure practice by the cryptography community. + + +The use of TLS v1.2 ensures compatibility with a wide range of platforms and +enables seamless communication between different systems that do not yet have +TLS v1.3 support. + +The only drawback depends on whether the framework used is outdated: its TLS +v1.2 settings may enable older and insecure cipher suites that are deprecated +as insecure. + +On the other hand, TLS v1.3 removes support for older and weaker cryptographic +algorithms, eliminates known vulnerabilities from previous TLS versions, and +improves performance. + diff --git a/rules/S4423/common/resources/articles.adoc b/rules/S4423/common/resources/articles.adoc new file mode 100644 index 0000000000..c4e3fcc34d --- /dev/null +++ b/rules/S4423/common/resources/articles.adoc @@ -0,0 +1,8 @@ +=== Articles & blog posts + +* https://en.wikipedia.org/wiki/Padding_oracle_attack[Wikipedia, Padding Oracle Attack] +* https://en.wikipedia.org/wiki/Chosen-ciphertext_attack[Wikipedia, Chosen-Ciphertext Attack] +* https://en.wikipedia.org/wiki/Chosen-plaintext_attack[Wikipedia, Chosen-Plaintext Attack] +* https://en.wikipedia.org/wiki/Semantic_security[Wikipedia, Semantically Secure Cryptosystems] +* https://en.wikipedia.org/wiki/Optimal_asymmetric_encryption_padding[Wikipedia, OAEP] +* https://en.wikipedia.org/wiki/Galois/Counter_Mode[Wikipedia, Galois/Counter Mode] diff --git a/rules/S4423/common/resources/docs.adoc b/rules/S4423/common/resources/docs.adoc new file mode 100644 index 0000000000..e69de29bb2 diff --git a/rules/S4423/common/resources/presentations.adoc b/rules/S4423/common/resources/presentations.adoc new file mode 100644 index 0000000000..e69de29bb2 diff --git a/rules/S4423/common/resources/standards.adoc b/rules/S4423/common/resources/standards.adoc new file mode 100644 index 0000000000..f539050d38 --- /dev/null +++ b/rules/S4423/common/resources/standards.adoc @@ -0,0 +1,6 @@ +=== Standards + +* https://owasp.org/Top10/A02_2021-Cryptographic_Failures/[OWASP Top 10 2021 Category A2] - Cryptographic Failures +* https://owasp.org/www-project-top-ten/2017/A6_2017-Security_Misconfiguration[OWASP Top 10 2017 Category A6] - Security Misconfiguration +* https://cwe.mitre.org/data/definitions/327[MITRE, CWE-327] - Use of a Broken or Risky Cryptographic Algorithm +* https://www.sans.org/top25-software-errors/#cat3[SANS Top 25] - Porous Defenses diff --git a/rules/S4423/csharp/how-to-fix-it/dotnet.adoc b/rules/S4423/csharp/how-to-fix-it/dotnet.adoc new file mode 100644 index 0000000000..a9026eace6 --- /dev/null +++ b/rules/S4423/csharp/how-to-fix-it/dotnet.adoc @@ -0,0 +1,61 @@ +== How to fix it in .NET + +=== Code examples + +==== Noncompliant code example + +These samples use TLSv1.0 as the default TLS algorithm, which is cryptographically weak. + +[source,csharp,diff-id=1,diff-type=noncompliant] +---- +using System.Net; + +public void encrypt() +{ + ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls; // Noncompliant +} +---- + +[source,csharp,diff-id=2,diff-type=noncompliant] +---- +using System.Net.Http; +using System.Security.Authentication; + +public void encrypt() +{ + new HttpClientHandler + { + SslProtocols = SslProtocols.Tls // Noncompliant + }; +} +---- + +==== Compliant solution + +[source,csharp,diff-id=1,diff-type=compliant] +---- +Using System.Net; + +public void encrypt() +{ + ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 | SecurityProtocolType.Tls13; +} +---- + +[source,csharp,diff-id=2,diff-type=compliant] +---- +using System.Net.Http; +using System.Security.Authentication; + +public void encrypt() +{ + new HttpClientHandler + { + SslProtocols = SslProtocols.Tls12 + }; +} +---- + +=== How does this work? + +include::../../common/fix/fix.adoc[] diff --git a/rules/S4423/csharp/rule.adoc b/rules/S4423/csharp/rule.adoc index f0d57185c5..957c742819 100644 --- a/rules/S4423/csharp/rule.adoc +++ b/rules/S4423/csharp/rule.adoc @@ -1,64 +1,26 @@ + +include::../summary.adoc[] + == Why is this an issue? -Older versions of SSL/TLS protocol like "SSLv3" have been proven to be insecure. +include::../rationale.adoc[] +include::../impact.adoc[] -This rule raises an issue when an SSL/TLS is configured at application level with an insecure version (ie: a protocol different from "TLSv1.2" or "TLSv1.3"). +// How to fix it section - -No issue is raised when the choice of the SSL/TLS version relies on the OS configuration. Be aware that the latest version of https://docs.microsoft.com/en-us/windows/win32/secauthn/protocols-in-tls-ssl\--schannel-ssp-[Windows 10 and Windows Server 2016 have TLSv1.0 and TLSv1.1 enabled by default]. Administrators can configure the OS to enforce TLSv1.2 minumum by https://docs.microsoft.com/en-us/windows-server/security/tls/tls-registry-settings[updateing registry settings] or by applying a group policy. - -=== Noncompliant code example - -[source,csharp] ----- -ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls; // Noncompliant; legacy version TLSv1 is enabled ----- - -For https://docs.microsoft.com/en-us/dotnet/api/system.net.http.httpclient[System.Net.Http.HttpClient] - -[source,csharp] ----- -new HttpClientHandler -{ - SslProtocols = SslProtocols.Tls // Noncompliant; legacy version TLSv1 is enabled -}; ----- - -=== Compliant solution - -[source,csharp] ----- -ServicePointManager.SecurityProtocol = SecurityProtocolType.SystemDefault; // Compliant; choice of the SSL/TLS versions rely on the OS configuration -ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 | SecurityProtocolType.Tls13; // Compliant ----- - -For https://docs.microsoft.com/en-us/dotnet/api/system.net.http.httpclient[System.Net.Http.HttpClient] - -[source,csharp] ----- -new HttpClientHandler -{ - SslProtocols = SslProtocols.Tls12 // Compliant -}; - -new HttpClientHandler -{ - SslProtocols = SslProtocols.None // Compliant; choice of the TLS versions rely on the OS configuration -}; ----- +include::how-to-fix-it/dotnet.adoc[] == Resources -* https://owasp.org/Top10/A02_2021-Cryptographic_Failures/[OWASP Top 10 2021 Category A2] - Cryptographic Failures -* https://owasp.org/Top10/A07_2021-Identification_and_Authentication_Failures/[OWASP Top 10 2021 Category A7] - Identification and Authentication Failures -* https://www.owasp.org/www-project-top-ten/2017/A3_2017-Sensitive_Data_Exposure[OWASP Top 10 2017 Category A3] - Sensitive Data Exposure -* https://owasp.org/www-project-top-ten/2017/A6_2017-Security_Misconfiguration[OWASP Top 10 2017 Category A6] - Security Misconfiguration -* https://cwe.mitre.org/data/definitions/326[MITRE, CWE-327] - Inadequate Encryption Strength -* https://cwe.mitre.org/data/definitions/327[MITRE, CWE-326] - Use of a Broken or Risky Cryptographic Algorithm -* https://www.sans.org/top25-software-errors/#cat3[SANS Top 25] - Porous Defenses -* https://github.com/ssllabs/research/wiki/SSL-and-TLS-Deployment-Best-Practices#22-use-secure-protocols[SSL and TLS Deployment Best Practices - Use secure protocols] -* https://docs.microsoft.com/en-us/dotnet/framework/network-programming/tls[Transport Layer Security (TLS) best practices with the .NET Framework] +include::../common/resources/docs.adoc[] + +include::../common/resources/articles.adoc[] + +include::../common/resources/presentations.adoc[] + +include::../common/resources/standards.adoc[] + ifdef::env-github,rspecator-view[] @@ -68,20 +30,10 @@ ifdef::env-github,rspecator-view[] include::../message.adoc[] -include::../highlighting.adoc[] - ''' == Comments And Links (visible only on this page) -=== on 14 Dec 2020, 13:45:35 Čaba Šagi wrote: -Additional cases to cover: - -* The default value of  ServicePointManager.SecurityProtocol is unsecure for .net framework versions earlier than 4.7. -* The default SslProtocol for https://docs.microsoft.com/en-us/dotnet/api/system.net.security.sslstream.authenticateasclient?view=net-5.0#System_Net_Security_SslStream_AuthenticateAsClient_System_String_[SSLStream] is unsecure for framework versions earlier than 4.7 - -  - include::../comments-and-links.adoc[] endif::env-github,rspecator-view[] diff --git a/rules/S4423/docker/how-to-fix-it/curl.adoc b/rules/S4423/docker/how-to-fix-it/curl.adoc new file mode 100644 index 0000000000..094bee69a0 --- /dev/null +++ b/rules/S4423/docker/how-to-fix-it/curl.adoc @@ -0,0 +1,26 @@ +== How to fix it in cURL + +=== Code examples + +==== Noncompliant code example + +[source,docker,diff-id=1,diff-type=noncompliant] +---- +FROM ubuntu:22.04 + +# Noncompliant +RUN curl --tlsv1.0 -O https://tlsv1-0.example.com/downloads/install.sh +---- + +==== Compliant solution + +[source,docker,diff-id=1,diff-type=compliant] +---- +FROM ubuntu:22.04 + +RUN curl --tlsv1.2 -O https://tlsv1-3.example.com/downloads/install.sh +---- + +=== How does this work? + +include::../../common/fix/fix.adoc[] diff --git a/rules/S4423/docker/how-to-fix-it/wget.adoc b/rules/S4423/docker/how-to-fix-it/wget.adoc new file mode 100644 index 0000000000..ac681445c9 --- /dev/null +++ b/rules/S4423/docker/how-to-fix-it/wget.adoc @@ -0,0 +1,26 @@ +== How to fix it in Wget + +=== Code examples + +==== Noncompliant code example + +[source,docker,diff-id=1,diff-type=noncompliant] +---- +FROM ubuntu:22.04 + +# Noncompliant +RUN wget --secure-protocol TLSv1_1 https://example.com/downloads/install.sh +---- + +==== Compliant solution + +[source,docker,diff-id=1,diff-type=compliant] +---- +FROM ubuntu:22.04 + +RUN wget --secure-protocol TLSv1_2 https://example.com/downloads/install.sh +---- + +=== How does this work? + +include::../../common/fix/fix.adoc[] diff --git a/rules/S4423/docker/rule.adoc b/rules/S4423/docker/rule.adoc index 44b007bc6f..caad503305 100644 --- a/rules/S4423/docker/rule.adoc +++ b/rules/S4423/docker/rule.adoc @@ -1,36 +1,26 @@ +include::../summary.adoc[] + == Why is this an issue? -include::../description.adoc[] +include::../rationale.adoc[] -=== Noncompliant code example -HTTP request tools such as `curl`, `wget` and `Invoke-WebRequest` offer the option to choose the version of SSL/TLS that will be used for requests. -The following example successfully requests data from a server with an insecure version of TLS. Thus, it is possible that the response was intercepted or tampered with by a third party. +include::../impact.adoc[] -[source,docker] ----- -FROM ubuntu:22.04 +// How to fix it section +include::how-to-fix-it/curl.adoc[] -# Noncompliant -RUN curl --tlsv1.0 -O https://tlsv1-0.example.com/downloads/install.sh ----- - -=== Compliant solution -Choosing a recent, secure version of TLS ensures that the created TLS session is secure and cannot be intercepted. -In this example, the minimal version of TLS is set to TLSv1.2, guaranteeing that requests can only be sent over TLSv1.2 or TLSv1.3. - -[source,docker] ----- -FROM ubuntu:22.04 - -RUN curl --tlsv1.2 -O https://tlsv1-3.example.com/downloads/install.sh ----- +include::how-to-fix-it/wget.adoc[] == Resources -* https://cwe.mitre.org/data/definitions/326[MITRE, CWE-327] - Inadequate Encryption Strength -* https://cwe.mitre.org/data/definitions/327[MITRE, CWE-326] - Use of a Broken or Risky Cryptographic Algorithm -* https://www.sans.org/top25-software-errors/#cat3[SANS Top 25] - Porous Defenses -* https://github.com/ssllabs/research/wiki/SSL-and-TLS-Deployment-Best-Practices#22-use-secure-protocols[SSL and TLS Deployment Best Practices] - Use secure protocols +include::../common/resources/docs.adoc[] + +include::../common/resources/articles.adoc[] + +include::../common/resources/presentations.adoc[] + +include::../common/resources/standards.adoc[] + ifdef::env-github,rspecator-view[] @@ -42,9 +32,6 @@ ifdef::env-github,rspecator-view[] Change this code to enforce TLS 1.2 or above. - -include::../highlighting.adoc[] - ''' == Comments And Links (visible only on this page) diff --git a/rules/S4423/go/metadata.json b/rules/S4423/go/metadata.json deleted file mode 100644 index 1797133380..0000000000 --- a/rules/S4423/go/metadata.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - -} diff --git a/rules/S4423/go/rule.adoc b/rules/S4423/go/rule.adoc deleted file mode 100644 index f5db9e87ac..0000000000 --- a/rules/S4423/go/rule.adoc +++ /dev/null @@ -1,18 +0,0 @@ -include::../rule.adoc[] - -ifdef::env-github,rspecator-view[] - -''' -== Implementation Specification -(visible only on this page) - -include::../message.adoc[] - -include::../highlighting.adoc[] - -''' -== Comments And Links -(visible only on this page) - -include::../comments-and-links.adoc[] -endif::env-github,rspecator-view[] diff --git a/rules/S4423/highlighting.adoc b/rules/S4423/highlighting.adoc deleted file mode 100644 index 3fedaf6eec..0000000000 --- a/rules/S4423/highlighting.adoc +++ /dev/null @@ -1,4 +0,0 @@ -=== Highlighting - -SSLContext.getInstance invocation - diff --git a/rules/S4423/impact.adoc b/rules/S4423/impact.adoc new file mode 100644 index 0000000000..b393b304d1 --- /dev/null +++ b/rules/S4423/impact.adoc @@ -0,0 +1,34 @@ +=== What is the potential impact? +After retrieving encrypted data and performing cryptographic attacks on it on a +given timeframe, attackers can recover the plaintext that encryption was +supposed to protect. + +Depending on the recovered data, the impact may vary. + +Below are some real-world scenarios that illustrate the potential impact of an +attacker exploiting the vulnerability. + +==== Additional attack surface +By modifying the plaintext of the encrypted message, an attacker may be able to +trigger additional vulnerabilities in the code. An attacker can further exploit +a system to obtain more information. + +Encrypted values are often considered trustworthy because it would not be +possible for a third party to modify them under normal circumstances. + +==== Breach of confidentiality and privacy +When encrypted data contains personal or sensitive information, its retrieval +by an attacker can lead to privacy violations, identity theft, financial loss, +reputational damage, or unauthorized access to confidential systems. + +In this scenario, the company, its employees, users, and partners could be +seriously affected. + +The impact is twofold, as data breaches and exposure of encrypted data can +undermine trust in the organization, as customers, clients and stakeholders may +lose confidence in the organization's ability to protect their sensitive data. + +==== Legal and compliance issues +In many industries and locations, there are legal and compliance requirements +to protect sensitive data. If encrypted data is compromised and the plaintext +can be recovered, companies face legal consequences, penalties, or violations +of privacy laws. diff --git a/rules/S4423/java/how-to-fix-it/java-cryptographic-extension.adoc b/rules/S4423/java/how-to-fix-it/java-cryptographic-extension.adoc new file mode 100644 index 0000000000..8756073d44 --- /dev/null +++ b/rules/S4423/java/how-to-fix-it/java-cryptographic-extension.adoc @@ -0,0 +1,39 @@ +== How to fix it in Java Cryptographic Extension + +=== Code examples + +==== Noncompliant code example + +[source,java,diff-id=1,diff-type=noncompliant] +---- +import javax.net.ssl.SSLContext; +import java.security.NoSuchAlgorithmException; + +public static void main(String[] args) { + try { + SSLContext.getInstance("TLSv1.1"); // Noncompliant + } catch (NoSuchAlgorithmException e) { + // ... + } +} +---- + +==== Compliant solution + +[source,java,diff-id=1,diff-type=compliant] +---- +import javax.net.ssl.SSLContext; +import java.security.NoSuchAlgorithmException; + +public static void main(String[] args) { + try { + SSLContext.getInstance("TLSv1.2"); + } catch (NoSuchAlgorithmException e) { + // ... + } +} +---- + +=== How does this work? + +include::../../common/fix/fix.adoc[] diff --git a/rules/S4423/java/how-to-fix-it/okhttp.adoc b/rules/S4423/java/how-to-fix-it/okhttp.adoc new file mode 100644 index 0000000000..5b7e7c9954 --- /dev/null +++ b/rules/S4423/java/how-to-fix-it/okhttp.adoc @@ -0,0 +1,36 @@ + +== How to fix it in OkHttp + +=== Code examples + +==== Noncompliant code example + +[source,java,diff-id=1,diff-type=noncompliant] +---- +import okhttp3.ConnectionSpec; +import okhttp3.TlsVersion; + +public static void main(String[] args) { + new ConnectionSpec.Builder(ConnectionSpec.MODERN_TLS) + .tlsVersions(TlsVersion.TLS_1_1) // Noncompliant + .build(); +} +---- + +==== Compliant solution + +[source,java,diff-id=1,diff-type=compliant] +---- +import okhttp3.ConnectionSpec; +import okhttp3.TlsVersion; + +public static void main(String[] args) { + new ConnectionSpec.Builder(ConnectionSpec.MODERN_TLS) + .tlsVersions(TlsVersion.TLS_1_2) + .build(); +} +---- + +=== How does this work? + +include::../../common/fix/fix.adoc[] diff --git a/rules/S4423/java/rule.adoc b/rules/S4423/java/rule.adoc index 59cd632af0..24cc939d5c 100644 --- a/rules/S4423/java/rule.adoc +++ b/rules/S4423/java/rule.adoc @@ -1,54 +1,31 @@ + +include::../summary.adoc[] + == Why is this an issue? -include::../description.adoc[] +include::../rationale.adoc[] -=== Noncompliant code example +include::../impact.adoc[] -``++javax.net.ssl.SSLContext++`` library: +// How to fix it section -[source,java] ----- -context = SSLContext.getInstance("TLSv1.1"); // Noncompliant ----- +include::how-to-fix-it/java-cryptographic-extension.adoc[] -https://square.github.io/okhttp/[okhttp] library: - -[source,java] ----- -ConnectionSpec spec = new ConnectionSpec.Builder(ConnectionSpec.MODERN_TLS) - .tlsVersions(TlsVersion.TLS_1_1) // Noncompliant - .build(); ----- - -=== Compliant solution - -``++javax.net.ssl.SSLContext++`` library: - -[source,java] ----- -context = SSLContext.getInstance("TLSv1.2"); // Compliant ----- - -https://square.github.io/okhttp/[okhttp] library: - -[source,java] ----- -ConnectionSpec spec = new ConnectionSpec.Builder(ConnectionSpec.MODERN_TLS) - .tlsVersions(TlsVersion.TLS_1_2) // Compliant - .build(); ----- +include::how-to-fix-it/okhttp.adoc[] == Resources -* https://owasp.org/Top10/A02_2021-Cryptographic_Failures/[OWASP Top 10 2021 Category A2] - Cryptographic Failures -* https://owasp.org/Top10/A07_2021-Identification_and_Authentication_Failures/[OWASP Top 10 2021 Category A7] - Identification and Authentication Failures -* https://www.owasp.org/www-project-top-ten/2017/A3_2017-Sensitive_Data_Exposure[OWASP Top 10 2017 Category A3] - Sensitive Data Exposure -* https://owasp.org/www-project-top-ten/2017/A6_2017-Security_Misconfiguration[OWASP Top 10 2017 Category A6] - Security Misconfiguration -* https://cwe.mitre.org/data/definitions/326[MITRE, CWE-327] - Inadequate Encryption Strength -* https://cwe.mitre.org/data/definitions/327[MITRE, CWE-326] - Use of a Broken or Risky Cryptographic Algorithm -* https://www.sans.org/top25-software-errors/#cat3[SANS Top 25] - Porous Defenses -* https://blogs.oracle.com/java-platform-group/diagnosing-tls,-ssl,-and-https[Diagnosing TLS, SSL, and HTTPS] -* https://github.com/ssllabs/research/wiki/SSL-and-TLS-Deployment-Best-Practices#22-use-secure-protocols[SSL and TLS Deployment Best Practices - Use secure protocols] +include::../common/resources/docs.adoc[] + +include::../common/resources/articles.adoc[] + +include::../common/resources/presentations.adoc[] + +include::../common/resources/standards.adoc[] +* https://mobile-security.gitbook.io/masvs/security-requirements/0x08-v3-cryptography_verification_requirements[Mobile AppSec Verification Standard] - Cryptography Requirements +* https://owasp.org/www-project-mobile-top-10/2016-risks/m5-insufficient-cryptography[OWASP Mobile Top 10 2016 Category M5] - Insufficient Cryptography +* https://cwe.mitre.org/data/definitions/327[MITRE, CWE-327] - Use of a Broken or Risky Cryptographic Algorithm +* https://wiki.sei.cmu.edu/confluence/x/hDdGBQ[CERT, MSC61-J.] - Do not use insecure or weak cryptographic algorithms ifdef::env-github,rspecator-view[] @@ -58,11 +35,14 @@ ifdef::env-github,rspecator-view[] include::../message.adoc[] -include::../highlighting.adoc[] +=== Highlighting + +`SSLContext.getInstance` invocation ''' == Comments And Links (visible only on this page) include::../comments-and-links.adoc[] + endif::env-github,rspecator-view[] diff --git a/rules/S4423/javascript/how-to-fix-it/aws-cdk.adoc b/rules/S4423/javascript/how-to-fix-it/aws-cdk.adoc new file mode 100644 index 0000000000..3f21518327 --- /dev/null +++ b/rules/S4423/javascript/how-to-fix-it/aws-cdk.adoc @@ -0,0 +1,56 @@ +== How to fix it in AWS CDK + +=== Code examples + +==== Noncompliant code example + +[source,javascript,diff-id=1,diff-type=noncompliant] +---- +import { aws_apigateway as agw } from 'aws-cdk-lib'; +new agw.DomainName(this, 'Example', { + certificate: certificate, + domainName: domainName, + securityPolicy: agw.SecurityPolicy.TLS_1_0, // Noncompliant +}); +---- + +The resource `CfnDomain` uses a weak TLS security policy, by default. + +[source,javascript,diff-id=2,diff-type=noncompliant] +---- +import { aws_opensearchservice as os } from 'aws-cdk-lib'; + +new os.CfnDomain(this, 'Example', { + domainEndpointOptions: { + enforceHttps: true, + }, +}); // Noncompliant +---- + +==== Compliant solution + +[source,javascript,diff-id=1,diff-type=compliant] +---- +import { aws_apigateway as agw } from 'aws-cdk-lib'; +new agw.DomainName(this, 'Example', { + certificate: certificate, + domainName: domainName, + securityPolicy: agw.SecurityPolicy.TLS_1_2, +}); +---- + +[source,javascript,diff-id=2,diff-type=compliant] +---- +import { aws_opensearchservice as os } from 'aws-cdk-lib'; + +new os.CfnDomain(this, 'Example', { + domainEndpointOptions: { + enforceHttps: true, + tlsSecurityPolicy: 'Policy-Min-TLS-1-2-2019-07', + }, +}); +---- + +=== How does this work? + +include::../../common/fix/fix.adoc[] diff --git a/rules/S4423/javascript/how-to-fix-it/node-js.adoc b/rules/S4423/javascript/how-to-fix-it/node-js.adoc new file mode 100644 index 0000000000..7a36856471 --- /dev/null +++ b/rules/S4423/javascript/how-to-fix-it/node-js.adoc @@ -0,0 +1,116 @@ +== How to fix it in Node.js + +=== Code examples + +==== Noncompliant code example + +NodeJs offers multiple ways to set weak TLS protocols. For https and tls, +https://nodejs.org/api/tls.html#tlscreatesecurecontextoptions[these options] +are used and are used in other third-party libraries as well. + +The first is `secureProtocol`: + +[source,javascript,diff-id=1,diff-type=noncompliant] +---- +const https = require('node:https'); +const tls = require('node:tls'); + +let options = { + secureProtocol: 'TLSv1_method' // Noncompliant +}; + +let req = https.request(options, (res) => { }); +let socket = tls.connect(443, "www.example.com", options, () => { }); +---- + +The second is the combination of `minVersion` and `maxVerison`. Note that they +cannot be specified along with the `secureProtocol` option: + +[source,javascript,diff-id=2,diff-type=noncompliant] +---- +const https = require('node:https'); +const tls = require('node:tls'); + +let options = { + minVersion: 'TLSv1.1', // Noncompliant + maxVersion: 'TLSv1.2' +}; + +let req = https.request(options, (res) => { }); +let socket = tls.connect(443, "www.example.com", options, () => { }); +---- + +And `secureOptions`, which in this example instructs the OpenSSL protocol to +turn off some algorithms altogether. In general, this option might trigger side +effects and should be used carefully, if used at all. + +[source,javascript,diff-id=3,diff-type=noncompliant] +---- +const https = require('node:https'); +const tls = require('node:tls'); +const constants = require('node:crypto'): + +let options = { + secureOptions: + constants.SSL_OP_NO_SSLv2 + | constants.SSL_OP_NO_SSLv3 + | constants.SSL_OP_NO_TLSv1 +}; // Noncompliant + +let req = https.request(options, (res) => { }); +let socket = tls.connect(443, "www.example.com", options, () => { }); +---- + +==== Compliant solution + +[source,javascript,diff-id=1,diff-type=compliant] +---- +const https = require('node:https'); +const tls = require('node:tls'); + +let options = { + secureProtocol: 'TLSv1_2_method' +}; + +let req = https.request(options, (res) => { }); +let socket = tls.connect(443, "www.example.com", options, () => { }); +---- + +[source,javascript,diff-id=2,diff-type=compliant] +---- +const https = require('node:https'); +const tls = require('node:tls'); + +let options = { + minVersion: 'TLSv1.2', + maxVersion: 'TLSv1.2' +}; + +let req = https.request(options, (res) => { }); +let socket = tls.connect(443, "www.example.com", options, () => { }); + +---- + +Here, the goal is to turn on only TLSv1.2 and higher, by turning off all lower +versions: + +[source,javascript,diff-id=3,diff-type=compliant] +---- +const https = require('node:https'); +const tls = require('node:tls'); + +let options = { + secureOptions: + constants.SSL_OP_NO_SSLv2 + | constants.SSL_OP_NO_SSLv3 + | constants.SSL_OP_NO_TLSv1 + | constants.SSL_OP_NO_TLSv1_1 +}; + +let req = https.request(options, (res) => { }); +let socket = tls.connect(443, "www.example.com", options, () => { }); +---- + +=== How does this work? + +include::../../common/fix/fix.adoc[] diff --git a/rules/S4423/javascript/rule.adoc b/rules/S4423/javascript/rule.adoc index 2fec0c5dbc..ed848d0050 100644 --- a/rules/S4423/javascript/rule.adoc +++ b/rules/S4423/javascript/rule.adoc @@ -1,152 +1,28 @@ + +include::../summary.adoc[] + == Why is this an issue? -include::../description.adoc[] +include::../rationale.adoc[] -=== Noncompliant code example +include::../impact.adoc[] -``++secureProtocol++``, ``++minVersion++``/``++maxVersion++`` and ``++secureOptions++`` should not be set to use weak TLS protocols (TLSv1.1 and lower): +// How to fix it section -[source,javascript] ----- -let options = { - secureProtocol: 'TLSv1_method' // Noncompliant: TLS1.0 is insecure -}; +include::how-to-fix-it/node-js.adoc[] -let options = { - minVersion: 'TLSv1.1', // Noncompliant: TLS1.1 is insecure - maxVersion: 'TLSv1.2' -}; +include::how-to-fix-it/aws-cdk.adoc[] -let options = { - secureOptions: constants.SSL_OP_NO_SSLv2 | constants.SSL_OP_NO_SSLv3 | constants.SSL_OP_NO_TLSv1 -}; // Noncompliant TLS 1.1 (constants.SSL_OP_NO_TLSv1_1) is not disabled ----- +== Resources -https://nodejs.org/api/https.html[https] built-in module: +include::../common/resources/docs.adoc[] -[source,javascript] ----- -let req = https.request(options, (res) => { - res.on('data', (d) => { - process.stdout.write(d); - }); -}); // Noncompliant ----- +include::../common/resources/articles.adoc[] -https://nodejs.org/api/tls.html[tls] built-in module: +include::../common/resources/presentations.adoc[] -[source,javascript] ----- -let socket = tls.connect(443, "www.example.com", options, () => { }); // Noncompliant ----- +include::../common/resources/standards.adoc[] -https://www.npmjs.com/package/request[request] module: - -[source,javascript] ----- -let socket = request.get(options); ----- - -For https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_apigateway.DomainName.html[aws-cdk-lib.aws_apigateway.DomainName]: - -[source,javascript] ----- -import { aws_apigateway as agw } from 'aws-cdk-lib'; - -new agw.DomainName(this, 'Example', { - certificate: certificate, - domainName: domainName, - securityPolicy: agw.SecurityPolicy.TLS_1_0, // Noncompliant -}); ----- - -For https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_opensearchservice.Domain.html[aws-cdk-lib.aws_opensearchservice.Domain]: - -[source,javascript] ----- -import { aws_opensearchservice as os } from 'aws-cdk-lib'; - -new os.CfnDomain(this, 'Example', { - domainEndpointOptions: { - enforceHttps: true, - }, -}); // NonCompliant by default ----- - -=== Compliant solution - -Set either ``++secureProtocol++`` or ``++secureOptions++`` or ``++minVersion++`` to use secure protocols only (TLSv1.2 and higher): - -[source,javascript] ----- -let options = { - secureProtocol: 'TLSv1_2_method' -}; -// or -let options = { - secureOptions: constants.SSL_OP_NO_SSLv2 | constants.SSL_OP_NO_SSLv3 | constants.SSL_OP_NO_TLSv1 | constants.SSL_OP_NO_TLSv1_1 -}; -// or -let options = { - minVersion: 'TLSv1.2' -}; ----- - -https://nodejs.org/api/https.html[https] built-in module: - -[source,javascript] ----- -let req = https.request(options, (res) => { - res.on('data', (d) => { - process.stdout.write(d); - }); -}); ----- - - -https://nodejs.org/api/tls.html[tls] built-in module: - -[source,javascript] ----- -let socket = tls.connect(443, "www.example.com", options, () => { }); ----- - -https://www.npmjs.com/package/request[request] module: - -[source,javascript] ----- -let socket = request.get(options); ----- - -For https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_apigateway.DomainName.html[aws-cdk-lib.aws_apigateway.DomainName]: - -[source,javascript] ----- -import { aws_apigateway as agw } from 'aws-cdk-lib'; - -new agw.DomainName(this, 'Example', { - certificate: certificate, - domainName: domainName, - securityPolicy: agw.SecurityPolicy.TLS_1_2, -}); ----- - -For https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_opensearchservice.Domain.html[aws-cdk-lib.aws_opensearchservice.Domain]: - -[source,javascript] ----- -import { aws_opensearchservice as os } from 'aws-cdk-lib'; - -new os.CfnDomain(this, 'Example', { - domainEndpointOptions: { - enforceHttps: true, - tlsSecurityPolicy: 'Policy-Min-TLS-1-2-2019-07', - }, -}); ----- - -include::../see.adoc[] -* https://docs.aws.amazon.com/apigateway/latest/developerguide/apigateway-custom-domain-tls-version.html[Amazon API Gateway] - Choosing a minimum TLS version ifdef::env-github,rspecator-view[] @@ -169,9 +45,6 @@ Change this code to enforce TLS 1.2 or above. Omitting "tlsSecurityPolicy" enables a deprecated version of TLS. Set it to enforce TLS 1.2 or above. - -include::../highlighting.adoc[] - ''' == Comments And Links (visible only on this page) diff --git a/rules/S4423/kotlin/how-to-fix-it/java-cryptographic-extension.adoc b/rules/S4423/kotlin/how-to-fix-it/java-cryptographic-extension.adoc new file mode 100644 index 0000000000..adff55e118 --- /dev/null +++ b/rules/S4423/kotlin/how-to-fix-it/java-cryptographic-extension.adoc @@ -0,0 +1,39 @@ +== How to fix it in Java Cryptographic Extension + +=== Code examples + +==== Noncompliant code example + +[source,kotlin,diff-id=1,diff-type=noncompliant] +---- +import javax.net.ssl.SSLContext; +import java.security.NoSuchAlgorithmException; + +fun main(args: Array) { + try { + SSLContext.getInstance("TLSv1.1"); // Noncompliant + } catch (e: NoSuchAlgorithmException) { + // ... + } +} +---- + +==== Compliant solution + +[source,kotlin,diff-id=1,diff-type=compliant] +---- +import javax.net.ssl.SSLContext; +import java.security.NoSuchAlgorithmException; + +fun main(args: Array) { + try { + SSLContext.getInstance("TLSv1.2"); + } catch (e: NoSuchAlgorithmException) { + // ... + } +} +---- + +=== How does this work? + +include::../../common/fix/fix.adoc[] diff --git a/rules/S4423/kotlin/how-to-fix-it/okhttp.adoc b/rules/S4423/kotlin/how-to-fix-it/okhttp.adoc new file mode 100644 index 0000000000..c12cecb46a --- /dev/null +++ b/rules/S4423/kotlin/how-to-fix-it/okhttp.adoc @@ -0,0 +1,35 @@ +== How to fix it in OkHttp + +=== Code examples + +==== Noncompliant code example + +[source,kotlin,diff-id=1,diff-type=noncompliant] +---- +import okhttp3.ConnectionSpec; +import okhttp3.TlsVersion; + +fun main(args: Array) { + ConnectionSpec.Builder(ConnectionSpec.MODERN_TLS) + .tlsVersions(TlsVersion.TLS_1_1) // Noncompliant + .build(); +} +---- + +==== Compliant solution + +[source,kotlin,diff-id=1,diff-type=compliant] +---- +import okhttp3.ConnectionSpec; +import okhttp3.TlsVersion; + +fun main(args: Array) { + ConnectionSpec.Builder(ConnectionSpec.MODERN_TLS) + .tlsVersions(TlsVersion.TLS_1_2) + .build(); +} +---- + +=== How does this work? + +include::../../common/fix/fix.adoc[] diff --git a/rules/S4423/kotlin/rule.adoc b/rules/S4423/kotlin/rule.adoc index f392b4fe93..0be7b3bf6c 100644 --- a/rules/S4423/kotlin/rule.adoc +++ b/rules/S4423/kotlin/rule.adoc @@ -1,44 +1,31 @@ + +include::../summary.adoc[] + == Why is this an issue? -include::../description.adoc[] +include::../rationale.adoc[] -=== Noncompliant code example +include::../impact.adoc[] -``++javax.net.ssl.SSLContext++`` library: +// How to fix it section -[source,kotlin] ----- -val sc: SSLContext = SSLContext.getInstance("TLSv1.1") // Noncompliant ----- +include::how-to-fix-it/java-cryptographic-extension.adoc[] -https://square.github.io/okhttp/[okhttp] library: +include::how-to-fix-it/okhttp.adoc[] -[source,kotlin] ----- -val spec: ConnectionSpec = ConnectionSpec.Builder(ConnectionSpec.MODERN_TLS) - .tlsVersions(TlsVersion.TLS_1_1) // Noncompliant - .build() ----- +== Resources -=== Compliant solution +include::../common/resources/docs.adoc[] -``++javax.net.ssl.SSLContext++`` library: +include::../common/resources/articles.adoc[] -[source,kotlin] ----- -val sc: SSLContext = SSLContext.getInstance("TLSv1.2") // Compliant ----- +include::../common/resources/presentations.adoc[] -https://square.github.io/okhttp/[okhttp] library: - -[source,kotlin] ----- -val spec: ConnectionSpec = ConnectionSpec.Builder(ConnectionSpec.MODERN_TLS) - .tlsVersions(TlsVersion.TLS_1_2) // Compliant - .build() ----- - -include::../see.adoc[] +include::../common/resources/standards.adoc[] +* https://mobile-security.gitbook.io/masvs/security-requirements/0x08-v3-cryptography_verification_requirements[Mobile AppSec Verification Standard] - Cryptography Requirements +* https://owasp.org/www-project-mobile-top-10/2016-risks/m5-insufficient-cryptography[OWASP Mobile Top 10 2016 Category M5] - Insufficient Cryptography +* https://cwe.mitre.org/data/definitions/327[MITRE, CWE-327] - Use of a Broken or Risky Cryptographic Algorithm +* https://wiki.sei.cmu.edu/confluence/x/hDdGBQ[CERT, MSC61-J.] - Do not use insecure or weak cryptographic algorithms ifdef::env-github,rspecator-view[] @@ -48,11 +35,15 @@ ifdef::env-github,rspecator-view[] include::../message.adoc[] -include::../highlighting.adoc[] +=== Highlighting + +`SSLContext.getInstance` invocation + ''' == Comments And Links (visible only on this page) include::../comments-and-links.adoc[] + endif::env-github,rspecator-view[] diff --git a/rules/S4423/php/how-to-fix-it/core.adoc b/rules/S4423/php/how-to-fix-it/core.adoc new file mode 100644 index 0000000000..94afd2b29e --- /dev/null +++ b/rules/S4423/php/how-to-fix-it/core.adoc @@ -0,0 +1,49 @@ + +== How to fix it in Core PHP + +=== Code examples + +==== Noncompliant code example + +[source,php,diff-id=1,diff-type=noncompliant] +---- +$opts = array( + 'ssl' => [ + 'crypto_method' => STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT // Noncompliant + ], + 'http'=>array( + 'method'=>"GET" + ) +); + +$context = stream_context_create($opts); + +$fp = fopen('https://www.example.com', 'r', false, $context); +fpassthru($fp); +fclose($fp); +---- + +==== Compliant solution + +[source,php,diff-id=1,diff-type=compliant] +---- +$opts = array( + 'ssl' => [ + 'crypto_method' => STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT + ], + 'http'=>array( + 'method'=>"GET" + ) +); + +$context = stream_context_create($opts); + +$fp = fopen('https://www.example.com', 'r', false, $context); +fpassthru($fp); +fclose($fp); +---- + +=== How does this work? + +include::../../common/fix/fix.adoc[] + diff --git a/rules/S4423/php/rule.adoc b/rules/S4423/php/rule.adoc index 6bfab339da..a733f4e84e 100644 --- a/rules/S4423/php/rule.adoc +++ b/rules/S4423/php/rule.adoc @@ -1,31 +1,26 @@ + +include::../summary.adoc[] + == Why is this an issue? -include::../description.adoc[] +include::../rationale.adoc[] -=== Noncompliant code example +include::../impact.adoc[] -[source,php] ----- -$ctx = stream_context_create([ - 'ssl' => [ - 'crypto_method' => - STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT // Noncompliant - ], -]); ----- +// How to fix it section -=== Compliant solution +include::how-to-fix-it/core.adoc[] -[source,php] ----- -$ctx = stream_context_create([ - 'ssl' => [ - 'crypto_method' => STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT - ], -]); ----- +== Resources + +include::../common/resources/docs.adoc[] + +include::../common/resources/articles.adoc[] + +include::../common/resources/presentations.adoc[] + +include::../common/resources/standards.adoc[] -include::../see.adoc[] ifdef::env-github,rspecator-view[] @@ -35,11 +30,10 @@ ifdef::env-github,rspecator-view[] include::../message.adoc[] -include::../highlighting.adoc[] - ''' == Comments And Links (visible only on this page) include::../comments-and-links.adoc[] + endif::env-github,rspecator-view[] diff --git a/rules/S4423/python/how-to-fix-it/aws-cdk.adoc b/rules/S4423/python/how-to-fix-it/aws-cdk.adoc new file mode 100644 index 0000000000..f5bfef172a --- /dev/null +++ b/rules/S4423/python/how-to-fix-it/aws-cdk.adoc @@ -0,0 +1,67 @@ +== How to fix it in AWS CDK + +=== Code examples + +==== Noncompliant code example + +[source,python,diff-id=1,diff-type=noncompliant] +---- +from aws_cdk.aws_apigateway import DomainName, SecurityPolicy + +class ExampleStack(Stack): + def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None: + super().__init__(scope, construct_id, **kwargs) + DomainName(self, "example", + domain_name="example.com", + certificate=certificate, + security_policy=SecurityPolicy.TLS_1_0 # Noncompliant + ) +---- + +By default, AWS's OpenSearch service `CfnDomains` enables TLS 1.0, a weak +cryptographic algorithm. + +[source,python,diff-id=2,diff-type=noncompliant] +---- +from aws_cdk.aws_opensearchservice import CfnDomain, EngineVersion + +class ExampleStack(Stack): + def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None: + super().__init__(scope, construct_id, **kwargs) + CfnDomain(self, "example", + version=EngineVersion.OPENSEARCH_1_3 + ) # Noncompliant +---- + +==== Compliant solution + +[source,python,diff-id=1,diff-type=compliant] +---- +from aws_cdk.aws_apigateway import DomainName, SecurityPolicy + +class ExampleStack(Stack): + def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None: + super().__init__(scope, construct_id, **kwargs) + DomainName(self, "example", + domain_name="example.com", + certificate=certificate, + security_policy=SecurityPolicy.TLS_1_2 + ) +---- + +[source,python,diff-id=2,diff-type=compliant] +---- +from aws_cdk.aws_opensearchservice import CfnDomain, EngineVersion +class ExampleStack(Stack): + def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None: + super().__init__(scope, construct_id, **kwargs) + CfnDomain(self, "example", + version=EngineVersion.OPENSEARCH_1_3 + domain_endpoint_options=CfnDomain.DomainEndpointOptionsProperty( + tls_security_policy="Policy-Min-TLS-1-2-2019-07" + ) + ) +---- +=== How does this work? + +include::../../common/fix/fix.adoc[] diff --git a/rules/S4423/python/how-to-fix-it/openssl.adoc b/rules/S4423/python/how-to-fix-it/openssl.adoc new file mode 100644 index 0000000000..180d722522 --- /dev/null +++ b/rules/S4423/python/how-to-fix-it/openssl.adoc @@ -0,0 +1,26 @@ +== How to fix it in OpenSSL + +=== Code examples + +==== Noncompliant code example + +[source,python,diff-id=1,diff-type=noncompliant] +---- +from OpenSSL import SSL + +SSL.Context(SSL.SSLv3_METHOD) # Noncompliant +---- + +==== Compliant solution + +[source,python,diff-id=1,diff-type=compliant] +---- +from OpenSSL import SSL + +context = SSL.Context(SSL.TLS_SERVER_METHOD) +context.set_min_proto_version(SSL.TLS1_3_VERSION) +---- + +=== How does this work? + +include::../../common/fix/fix.adoc[] diff --git a/rules/S4423/python/how-to-fix-it/ssl.adoc b/rules/S4423/python/how-to-fix-it/ssl.adoc new file mode 100644 index 0000000000..464efc80a7 --- /dev/null +++ b/rules/S4423/python/how-to-fix-it/ssl.adoc @@ -0,0 +1,26 @@ +== How to fix it in Python Standard Library + +=== Code examples + +==== Noncompliant code example + +[source,python,diff-id=1,diff-type=noncompliant] +---- +import ssl + +ssl.SSLContext(ssl.PROTOCOL_SSLv3) # Noncompliant +---- + +==== Compliant solution + +[source,python,diff-id=1,diff-type=compliant] +---- +import ssl + +context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER) +context.minimum_version = ssl.TLSVersion.TLSv1_3 +---- + +=== How does this work? + +include::../../common/fix/fix.adoc[] diff --git a/rules/S4423/python/rule.adoc b/rules/S4423/python/rule.adoc index 3b4d523a52..61f71c8340 100644 --- a/rules/S4423/python/rule.adoc +++ b/rules/S4423/python/rule.adoc @@ -1,109 +1,38 @@ + +include::../summary.adoc[] + == Why is this an issue? -include::../description.adoc[] +include::../rationale.adoc[] -=== Noncompliant code example +include::../impact.adoc[] -[source,python] ----- -from OpenSSL import SSL +// How to fix it section +include::how-to-fix-it/ssl.adoc[] -SSL.Context(SSL.SSLv3_METHOD) # Noncompliant ----- +include::how-to-fix-it/openssl.adoc[] -[source,python] ----- -import ssl +include::how-to-fix-it/aws-cdk.adoc[] -ssl.SSLContext(ssl.PROTOCOL_SSLv3) # Noncompliant ----- +== Resources -For https://docs.aws.amazon.com/cdk/api/v1/python/aws_cdk.aws_apigateway/DomainName.html[aws_cdk.aws_apigateway.DomainName]: -[source,python] ----- -from aws_cdk.aws_apigateway import DomainName, SecurityPolicy -class ExampleStack(Stack): - def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None: - super().__init__(scope, construct_id, **kwargs) - DomainName(self, "example", - domain_name="example.com", - certificate=certificate, - security_policy=SecurityPolicy.TLS_1_0 # Noncompliant - ) ----- +include::../common/resources/docs.adoc[] -For https://docs.aws.amazon.com/cdk/api/v2/python/aws_cdk.aws_opensearchservice/CfnDomain.html[aws_cdk.aws_opensearchservice.CfnDomain]: -[source,python] ----- -from aws_cdk.aws_opensearchservice import CfnDomain, EngineVersion -class ExampleStack(Stack): - def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None: - super().__init__(scope, construct_id, **kwargs) - CfnDomain(self, "example", - version=EngineVersion.OPENSEARCH_1_3 - ) # Noncompliant: enables TLS 1.0 which is a deprecated version of the protocol ----- +include::../common/resources/articles.adoc[] -=== Compliant solution +include::../common/resources/presentations.adoc[] -[source,python] ----- -from OpenSSL import SSL +include::../common/resources/standards.adoc[] -context = SSL.Context(SSL.TLS_SERVER_METHOD) -context.set_min_proto_version(SSL.TLS1_3_VERSION) ----- - -[source,python] ----- -import ssl - -context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER) -context.minimum_version = ssl.TLSVersion.TLSv1_3 - ----- - -For https://docs.aws.amazon.com/cdk/api/v1/python/aws_cdk.aws_apigateway/DomainName.html[aws_cdk.aws_apigateway.DomainName]: -[source,python] ----- -from aws_cdk.aws_apigateway import DomainName, SecurityPolicy -class ExampleStack(Stack): - def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None: - super().__init__(scope, construct_id, **kwargs) - DomainName(self, "example", - domain_name="example.com", - certificate=certificate, - security_policy=SecurityPolicy.TLS_1_2 - ) ----- - -For https://docs.aws.amazon.com/cdk/api/v2/python/aws_cdk.aws_opensearchservice/CfnDomain.html[aws_cdk.aws_opensearchservice.CfnDomain]: -[source,python] ----- -from aws_cdk.aws_opensearchservice import CfnDomain, EngineVersion -class ExampleStack(Stack): - def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None: - super().__init__(scope, construct_id, **kwargs) - CfnDomain(self, "example", - version=EngineVersion.OPENSEARCH_1_3 - domain_endpoint_options=CfnDomain.DomainEndpointOptionsProperty( - tls_security_policy="Policy-Min-TLS-1-2-2019-07" - ) - ) ----- - -include::../see.adoc[] -* https://docs.aws.amazon.com/apigateway/latest/developerguide/apigateway-custom-domain-tls-version.html[Amazon API Gateway] - Choosing a minimum TLS version ifdef::env-github,rspecator-view[] ''' == Implementation Specification (visible only on this page) - === Message -==== OpenSSL and ssl modules +**OpenSSL and ssl modules** When the system default is used: @@ -113,21 +42,20 @@ In all other cases: > Change this code to enforce TLS 1.2 or above. -==== AWS APIGateway +**AWS APIGateway** -Change this code to enforce TLS 1.2 or above. +> Change this code to enforce TLS 1.2 or above. -==== AWS OpenSearch / Elasticsearch +**AWS OpenSearch / Elasticsearch** -Omitting "tls_security_policy" enables a deprecated version of TLS. Set it to enforce TLS 1.2 or above. -Change this code to enforce TLS 1.2 or above. +> Omitting "tls_security_policy" enables a deprecated version of TLS. Set it to enforce TLS 1.2 or above. - -include::../highlighting.adoc[] +> Change this code to enforce TLS 1.2 or above. ''' == Comments And Links (visible only on this page) include::../comments-and-links.adoc[] + endif::env-github,rspecator-view[] diff --git a/rules/S4423/rationale.adoc b/rules/S4423/rationale.adoc new file mode 100644 index 0000000000..5d495688df --- /dev/null +++ b/rules/S4423/rationale.adoc @@ -0,0 +1,28 @@ +Encryption algorithms are essential for protecting sensitive information and +ensuring secure communications in a variety of domains. They are used for +several important reasons: + +* Confidentiality, privacy, and intellectual property protection +* Security during transmission or on storage devices +* Data integrity, general trust, and authentication + +When selecting encryption algorithms, tools, or combinations, you should also +consider two things: + +1. No encryption is unbreakable. +2. The strength of an encryption algorithm is usually measured by the effort required to crack it within a reasonable time frame. + +For these reasons, as soon as cryptography is included in a project, it is +important to choose encryption algorithms that are considered strong and secure +by the cryptography community. + +To provide communication security over a network, SSL and TLS are generally +used. However, it is important to note that the following protocols are all +considered weak by the cryptographic community, and are officially deprecated: + +* SSL versions 1.0, 2.0 and 3.0 +* TLS versions 1.0 and 1.1 + +When these unsecured protocols are used, it is best practice to expect a breach: +that a user or organization with malicious intent will perform mathematical +attacks on this data after obtaining it by other means. diff --git a/rules/S4423/ruby/metadata.json b/rules/S4423/ruby/metadata.json deleted file mode 100644 index 1797133380..0000000000 --- a/rules/S4423/ruby/metadata.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - -} diff --git a/rules/S4423/ruby/rule.adoc b/rules/S4423/ruby/rule.adoc deleted file mode 100644 index f5db9e87ac..0000000000 --- a/rules/S4423/ruby/rule.adoc +++ /dev/null @@ -1,18 +0,0 @@ -include::../rule.adoc[] - -ifdef::env-github,rspecator-view[] - -''' -== Implementation Specification -(visible only on this page) - -include::../message.adoc[] - -include::../highlighting.adoc[] - -''' -== Comments And Links -(visible only on this page) - -include::../comments-and-links.adoc[] -endif::env-github,rspecator-view[] diff --git a/rules/S4423/rust/metadata.json b/rules/S4423/rust/metadata.json deleted file mode 100644 index 1797133380..0000000000 --- a/rules/S4423/rust/metadata.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - -} diff --git a/rules/S4423/rust/rule.adoc b/rules/S4423/rust/rule.adoc deleted file mode 100644 index f5db9e87ac..0000000000 --- a/rules/S4423/rust/rule.adoc +++ /dev/null @@ -1,18 +0,0 @@ -include::../rule.adoc[] - -ifdef::env-github,rspecator-view[] - -''' -== Implementation Specification -(visible only on this page) - -include::../message.adoc[] - -include::../highlighting.adoc[] - -''' -== Comments And Links -(visible only on this page) - -include::../comments-and-links.adoc[] -endif::env-github,rspecator-view[] diff --git a/rules/S4423/scala/metadata.json b/rules/S4423/scala/metadata.json deleted file mode 100644 index 1797133380..0000000000 --- a/rules/S4423/scala/metadata.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - -} diff --git a/rules/S4423/scala/rule.adoc b/rules/S4423/scala/rule.adoc deleted file mode 100644 index f5db9e87ac..0000000000 --- a/rules/S4423/scala/rule.adoc +++ /dev/null @@ -1,18 +0,0 @@ -include::../rule.adoc[] - -ifdef::env-github,rspecator-view[] - -''' -== Implementation Specification -(visible only on this page) - -include::../message.adoc[] - -include::../highlighting.adoc[] - -''' -== Comments And Links -(visible only on this page) - -include::../comments-and-links.adoc[] -endif::env-github,rspecator-view[] diff --git a/rules/S4423/solidity/metadata.json b/rules/S4423/solidity/metadata.json deleted file mode 100644 index 1797133380..0000000000 --- a/rules/S4423/solidity/metadata.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - -} diff --git a/rules/S4423/solidity/rule.adoc b/rules/S4423/solidity/rule.adoc deleted file mode 100644 index f5db9e87ac..0000000000 --- a/rules/S4423/solidity/rule.adoc +++ /dev/null @@ -1,18 +0,0 @@ -include::../rule.adoc[] - -ifdef::env-github,rspecator-view[] - -''' -== Implementation Specification -(visible only on this page) - -include::../message.adoc[] - -include::../highlighting.adoc[] - -''' -== Comments And Links -(visible only on this page) - -include::../comments-and-links.adoc[] -endif::env-github,rspecator-view[] diff --git a/rules/S4423/summary.adoc b/rules/S4423/summary.adoc new file mode 100644 index 0000000000..c859d60496 --- /dev/null +++ b/rules/S4423/summary.adoc @@ -0,0 +1,2 @@ +This vulnerability exposes encrypted data to a number of +attacks whose goal is to recover the plaintext. diff --git a/rules/S4423/terraform/how-to-fix-it/aws-api-gateway.adoc b/rules/S4423/terraform/how-to-fix-it/aws-api-gateway.adoc new file mode 100644 index 0000000000..5354b9ba86 --- /dev/null +++ b/rules/S4423/terraform/how-to-fix-it/aws-api-gateway.adoc @@ -0,0 +1,51 @@ +== How to fix it in AWS API Gateway + +=== Code examples + +These code samples illustrate how to fix this issue in both APIGateway and +ApiGatewayV2. + +==== Noncompliant code example + +[source,terraform,diff-id=1,diff-type=noncompliant] +---- +resource "aws_api_gateway_domain_name" "example" { + domain_name = "api.example.com" + security_policy = "TLS_1_0" # Noncompliant +} +---- + +The ApiGatewayV2 uses a weak TLS version by default: + +[source,terraform,diff-id=2,diff-type=noncompliant] +---- +resource "aws_apigatewayv2_domain_name" "example" { + domain_name = "api.example.com" + domain_name_configuration {} # Noncompliant +} +---- + + +==== Compliant solution + +[source,terraform,diff-id=1,diff-type=compliant] +---- +resource "aws_api_gateway_domain_name" "example" { + domain_name = "api.example.com" + security_policy = "TLS_1_2" +} +---- + +[source,terraform,diff-id=2,diff-type=compliant] +---- +resource "aws_apigatewayv2_domain_name" "example" { + domain_name = "api.example.com" + domain_name_configuration { + security_policy = "TLS_1_2" + } +} +---- + +=== How does this work? + +include::../../common/fix/fix.adoc[] diff --git a/rules/S4423/terraform/how-to-fix-it/aws-opensearch.adoc b/rules/S4423/terraform/how-to-fix-it/aws-opensearch.adoc new file mode 100644 index 0000000000..1c468d5b60 --- /dev/null +++ b/rules/S4423/terraform/how-to-fix-it/aws-opensearch.adoc @@ -0,0 +1,33 @@ +== How to fix it in AWS OpenSearch + +=== Code examples + +==== Noncompliant code example + +[source,terraform,diff-id=1,diff-type=noncompliant] +---- +resource "aws_elasticsearch_domain" "example" { + domain_name = "example" + domain_endpoint_options { + enforce_https = true + tls_security_policy = "Policy-Min-TLS-1-0-2019-07" # Noncompliant + } +} +---- + +==== Compliant solution + +[source,terraform,diff-id=1,diff-type=compliant] +---- +resource "aws_elasticsearch_domain" "example" { + domain_name = "example" + domain_endpoint_options { + enforce_https = true + tls_security_policy = "Policy-Min-TLS-1-2-2019-07" + } +} +---- + +=== How does this work? + +include::../../common/fix/fix.adoc[] diff --git a/rules/S4423/terraform/how-to-fix-it/gcp-lb.adoc b/rules/S4423/terraform/how-to-fix-it/gcp-lb.adoc new file mode 100644 index 0000000000..17c74d8c01 --- /dev/null +++ b/rules/S4423/terraform/how-to-fix-it/gcp-lb.adoc @@ -0,0 +1,27 @@ +== How to fix it in GCP Load Balancers + +=== Code examples + +==== Noncompliant code example + +[source,terraform,diff-id=1,diff-type=noncompliant] +---- +resource "google_compute_ssl_policy" "example" { + name = "example" + min_tls_version = "TLS_1_0" # Noncompliant +} +---- + +==== Compliant solution + +[source,terraform,diff-id=1,diff-type=compliant] +---- +resource "google_compute_ssl_policy" "example" { + name = "example" + min_tls_version = "TLS_1_2" +} +---- + +=== How does this work? + +include::../../common/fix/fix.adoc[] diff --git a/rules/S4423/terraform/rule.adoc b/rules/S4423/terraform/rule.adoc index d1bb1b1245..3d4a519da6 100644 --- a/rules/S4423/terraform/rule.adoc +++ b/rules/S4423/terraform/rule.adoc @@ -1,97 +1,29 @@ +include::../summary.adoc[] + == Why is this an issue? -include::../description.adoc[] +include::../rationale.adoc[] -=== Noncompliant code example +include::../impact.adoc[] -For https://docs.aws.amazon.com/opensearch-service/index.html[Amazon OpenSearch domains]: +// How to fix it section +include::how-to-fix-it/aws-api-gateway.adoc[] -[source,terraform] ----- -resource "aws_elasticsearch_domain" "example" { - domain_name = "example" - domain_endpoint_options { - enforce_https = true - tls_security_policy = "Policy-Min-TLS-1-0-2019-07" # Noncompliant - } ----- +include::how-to-fix-it/aws-opensearch.adoc[] -For https://aws.amazon.com/api-gateway/[Amazon API Gateway]: +include::how-to-fix-it/gcp-lb.adoc[] -[source,terraform] ----- -resource "aws_api_gateway_domain_name" "example" { - domain_name = "api.example.com" - security_policy = "TLS_1_0" # Noncompliant -} ----- -[source,terraform] ----- -resource "aws_apigatewayv2_domain_name" "example" { - domain_name = "api.example.com" - domain_name_configuration {} # Noncompliant -} ----- +== Resources -For https://cloud.google.com/load-balancing/docs/use-ssl-policies[Google Cloud load balancers] +include::../common/resources/docs.adoc[] -[source,terraform] ----- -resource "google_compute_ssl_policy" "example" { - name = "example" - min_tls_version = "TLS_1_0" # Noncompliant - # ... -} ----- +include::../common/resources/articles.adoc[] -=== Compliant solution +include::../common/resources/presentations.adoc[] -For https://docs.aws.amazon.com/opensearch-service/index.html[Amazon OpenSearch domains]: +include::../common/resources/standards.adoc[] -[source,terraform] ----- -resource "aws_elasticsearch_domain" "example" { - domain_name = "example" - domain_endpoint_options { - enforce_https = true - tls_security_policy = "Policy-Min-TLS-1-2-2019-07" ----- - -For https://aws.amazon.com/api-gateway/[Amazon API Gateway]: - -[source,terraform] ----- -resource "aws_api_gateway_domain_name" "example" { - domain_name = "api.example.com" - security_policy = "TLS_1_2" -} ----- - -[source,terraform] ----- -resource "aws_apigatewayv2_domain_name" "example" { - domain_name = "api.example.com" - domain_name_configuration { - security_policy = "TLS_1_2" - } -} ----- - -For https://cloud.google.com/load-balancing/docs/use-ssl-policies[Google Cloud load balancers] -[source,terraform] ----- -resource "google_compute_ssl_policy" "example" { - name = "example" - min_tls_version = "TLS_1_2" - # ... -} ----- - -include::../see.adoc[] - -* https://docs.aws.amazon.com/apigateway/latest/developerguide/apigateway-custom-domain-tls-version.html[Amazon API Gateway] - Choosing a minimum TLS version -* https://cloud.google.com/load-balancing/docs/ssl-policies-concepts#defining_an_ssl_policy[Google Cloud Load Balancing] - Defining an SSL policy ifdef::env-github,rspecator-view[] @@ -168,6 +100,7 @@ For `google_compute_ssl_policy`: * Highlight resource if `min_tls_version` is not specified at all + ''' == Comments And Links (visible only on this page) diff --git a/rules/S4423/vbnet/how-to-fix-it/dotnet.adoc b/rules/S4423/vbnet/how-to-fix-it/dotnet.adoc new file mode 100644 index 0000000000..a07114e598 --- /dev/null +++ b/rules/S4423/vbnet/how-to-fix-it/dotnet.adoc @@ -0,0 +1,61 @@ +== How to fix it in .NET + +=== Code examples + +==== Noncompliant code example + +These samples use a default TLS algorithm, which is a weak cryptographical +algorithm: TLSv1.0. + +[source,vbnet,diff-id=1,diff-type=noncompliant] +---- +Imports System.Net +Imports System.Security.Authentication + +Public Sub Encrypt() + ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls ' Noncompliant +End Sub +---- + +[source,vbnet,diff-id=2,diff-type=noncompliant] +---- +Imports System.Net.Http +Imports System.Security.Authentication + +Public Sub Encrypt() + Dim Handler As New HttpClientHandler With { + .SslProtocols = SslProtocols.Tls ' Noncompliant + } +End Sub +---- + +==== Compliant solution + +[source,vbnet,diff-id=1,diff-type=compliant] +---- +Imports System.Net +Imports System.Security.Authentication + +Public Sub Encrypt() + ServicePointManager.SecurityProtocol = _ + SecurityProtocolType.Tls12 _ + Or SecurityProtocolType.Tls13 +End Sub + +---- + +[source,vbnet,diff-id=2,diff-type=compliant] +---- +Imports System.Net.Http +Imports System.Security.Authentication + +Public Sub Encrypt() + Dim Handler As New HttpClientHandler With { + .SslProtocols = SslProtocols.Tls12 + } +End Sub +---- + +=== How does this work? + +include::../../common/fix/fix.adoc[] diff --git a/rules/S4423/vbnet/rule.adoc b/rules/S4423/vbnet/rule.adoc index 5cbb4a06c5..957c742819 100644 --- a/rules/S4423/vbnet/rule.adoc +++ b/rules/S4423/vbnet/rule.adoc @@ -1,54 +1,26 @@ + +include::../summary.adoc[] + == Why is this an issue? -Older versions of SSL/TLS protocol like "SSLv3" have been proven to be insecure. +include::../rationale.adoc[] +include::../impact.adoc[] -This rule raises an issue when an SSL/TLS is configured at application level with an insecure version (ie: a protocol different from "TLSv1.2" or "TLSv1.3"). +// How to fix it section - -No issue is raised when the choice of the SSL/TLS version relies on the OS configuration. Be aware that the latest version of https://docs.microsoft.com/en-us/windows/win32/secauthn/protocols-in-tls-ssl\--schannel-ssp-[Windows 10 and Windows Server 2016 have TLSv1.0 and TLSv1.1 enabled by default]. Administrators can configure the OS to enforce TLSv1.2 minumum by https://docs.microsoft.com/en-us/windows-server/security/tls/tls-registry-settings[updateing registry settings] or by applying a group policy. - -=== Noncompliant code example - -[source,vbnet] ----- -ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls ' Noncompliant; legacy version TLSv1 is enabled ----- - -For https://docs.microsoft.com/en-us/dotnet/api/system.net.http.httpclient[System.Net.Http.HttpClient] - -[source,vbnet] ----- -Dim Handler As New HttpClientHandler With {.SslProtocols = SslProtocols.Tls} ' Noncompliant; legacy version TLSv1 Is enabled ----- - -=== Compliant solution - -[source,vbnet] ----- -ServicePointManager.SecurityProtocol = SecurityProtocolType.SystemDefault ' Compliant; choice Of the SSL/TLS versions rely On the OS configuration -ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 Or SecurityProtocolType.Tls13 ' Compliant ----- - -For https://docs.microsoft.com/en-us/dotnet/api/system.net.http.httpclient[System.Net.Http.HttpClient] - -[source,vbnet] ----- -Dim HandlerA As New HttpClientHandler With {.SslProtocols = SslProtocols.Tls12} ' Compliant -Dim HandlerB As New HttpClientHandler With {.SslProtocols = SslProtocols.None} ' Compliant; choice Of the TLS versions rely On the OS configuration ----- +include::how-to-fix-it/dotnet.adoc[] == Resources -* https://owasp.org/Top10/A02_2021-Cryptographic_Failures/[OWASP Top 10 2021 Category A2] - Cryptographic Failures -* https://owasp.org/Top10/A07_2021-Identification_and_Authentication_Failures/[OWASP Top 10 2021 Category A7] - Identification and Authentication Failures -* https://www.owasp.org/www-project-top-ten/2017/A3_2017-Sensitive_Data_Exposure[OWASP Top 10 2017 Category A3] - Sensitive Data Exposure -* https://owasp.org/www-project-top-ten/2017/A6_2017-Security_Misconfiguration[OWASP Top 10 2017 Category A6] - Security Misconfiguration -* https://cwe.mitre.org/data/definitions/326[MITRE, CWE-327] - Inadequate Encryption Strength -* https://cwe.mitre.org/data/definitions/327[MITRE, CWE-326] - Use of a Broken or Risky Cryptographic Algorithm -* https://www.sans.org/top25-software-errors/#cat3[SANS Top 25] - Porous Defenses -* https://github.com/ssllabs/research/wiki/SSL-and-TLS-Deployment-Best-Practices#22-use-secure-protocols[SSL and TLS Deployment Best Practices - Use secure protocols] -* https://docs.microsoft.com/en-us/dotnet/framework/network-programming/tls[Transport Layer Security (TLS) best practices with the .NET Framework] +include::../common/resources/docs.adoc[] + +include::../common/resources/articles.adoc[] + +include::../common/resources/presentations.adoc[] + +include::../common/resources/standards.adoc[] + ifdef::env-github,rspecator-view[] @@ -58,11 +30,10 @@ ifdef::env-github,rspecator-view[] include::../message.adoc[] -include::../highlighting.adoc[] - ''' == Comments And Links (visible only on this page) include::../comments-and-links.adoc[] + endif::env-github,rspecator-view[]