Vulnerability: scheme/webauthn.c in Glewlwyd SSO server through 2.5.3 has a buffer overflow during FIDO2 signature validation in webauthn registration.
Vulnerability ID: CVE-2021-40818
CWE: CWE-120
Severity score: 6.4
Project: https://github.com/babelouest/glewlwyd
Published: 2021-09-08
File: src/scheme/webauthn.c
Commit message: Fix fido2 signature validation bug
Commit author: babelouest

Vulnerable version (before fix):
 static json_t * check_attestation_fido_u2f(json_t * j_params, unsigned char * cr   gnutls_pubkey_t pubkey = NULL;   gnutls_x509_crt_t cert = NULL;   gnutls_datum_t cert_dat, data, signature, cert_issued_by;   unsigned char data_signed[200], client_data_hash[32], cert_export[32], cert_export_b64[64];   size_t data_signed_offset = 0, client_data_hash_len = 32, cert_export_len = 32, cert_export_b64_len = 0;      if (j_error != NULL) { static json_t * check_attestation_fido_u2f(json_t * j_params, unsigned char * cr         break;       }              // Build bytestring to verify signature       data_signed[0] = 0x0;       data_signed_offset = 1; static json_t * check_attestation_fido_u2f(json_t * j_params, unsigned char * cr       }            } while (0);          if (json_array_size(j_error)) {       j_return = json_pack("{sisO}", "result", G_ERROR_PARAM, "error", j_error);

Fixed version (after fix):
 static json_t * check_attestation_fido_u2f(json_t * j_params, unsigned char * cr   gnutls_pubkey_t pubkey = NULL;   gnutls_x509_crt_t cert = NULL;   gnutls_datum_t cert_dat, data, signature, cert_issued_by;   unsigned char * data_signed = NULL, client_data_hash[32], cert_export[32], cert_export_b64[64];   size_t data_signed_offset = 0, client_data_hash_len = 32, cert_export_len = 32, cert_export_b64_len = 0;      if (j_error != NULL) { static json_t * check_attestation_fido_u2f(json_t * j_params, unsigned char * cr         break;       }              if ((data_signed = o_malloc(rpid_hash_len+client_data_hash_len+credential_id_len+cert_x_len+cert_y_len+2)) == NULL) {         y_log_message(Y_LOG_LEVEL_DEBUG, "check_attestation_fido_u2f - Error allocating data_signed");         json_array_append_new(j_error, json_string("Internal error"));         break;       }              // Build bytestring to verify signature       data_signed[0] = 0x0;       data_signed_offset = 1; static json_t * check_attestation_fido_u2f(json_t * j_params, unsigned char * cr       }            } while (0);     o_free(data_signed);          if (json_array_size(j_error)) {       j_return = json_pack("{sisO}", "result", G_ERROR_PARAM, "error", j_error);

Patch:
patch: @@ -1543,7 +1543,7 @@ static json_t * check_attestation_fido_u2f(json_t * j_params, unsigned char * cr
   gnutls_pubkey_t pubkey = NULL;
   gnutls_x509_crt_t cert = NULL;
   gnutls_datum_t cert_dat, data, signature, cert_issued_by;
-  unsigned char data_signed[200], client_data_hash[32], cert_export[32], cert_export_b64[64];
+  unsigned char * data_signed = NULL, client_data_hash[32], cert_export[32], cert_export_b64[64];
   size_t data_signed_offset = 0, client_data_hash_len = 32, cert_export_len = 32, cert_export_b64_len = 0;
   
   if (j_error != NULL) {
@@ -1632,6 +1632,12 @@ static json_t * check_attestation_fido_u2f(json_t * j_params, unsigned char * cr
         break;
       }
       
+      if ((data_signed = o_malloc(rpid_hash_len+client_data_hash_len+credential_id_len+cert_x_len+cert_y_len+2)) == NULL) {
+        y_log_message(Y_LOG_LEVEL_DEBUG, "check_attestation_fido_u2f - Error allocating data_signed");
+        json_array_append_new(j_error, json_string("Internal error"));
+        break;
+      }
+      
       // Build bytestring to verify signature
       data_signed[0] = 0x0;
       data_signed_offset = 1;
@@ -1666,6 +1672,7 @@ static json_t * check_attestation_fido_u2f(json_t * j_params, unsigned char * cr
       }
       
     } while (0);
+    o_free(data_signed);
     
     if (json_array_size(j_error)) {
       j_return = json_pack("{sisO}", "result", G_ERROR_PARAM, "error", j_error);
path: src/scheme/webauthn.c