How to handle possible null values in CSFLE automatic encryption

I will try to provide as much information as possible regarding the issue I am currently facing, but first, some context. We have a .NET application that connects with MongoDB Atlas, and we utilise CSFLE in MongoDB Atlas, specifically using automatic encryption.

We currently have a schema that would look something like this

:Note: The schema below is exclusive of the first part that contains the encryption data key

{
  "bsonType": "object",
  "encryptMetadata": {
    "keyId": ["your-key-id"]
  },
 "properties":  <insert-sample-schemas-here>
}
{
  "contactInformation": {
    "bsonType": "object",
    "properties": {
      "phoneNumber": {
        "encrypt": {
          "bsonType": "string",
          "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random"
        }
      }
    }
  },
  "demographic": {
    "bsonType": "object",
    "properties": {
      "title": {
            "encrypt": {
              "bsonType": "string",
              "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random"
            }
          },
        ]
      },
      "firstName": {
        "encrypt": {
          "bsonType": "string",
          "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random"
        }
      }
    }
  }
}

Just another side note on all the sample schema’s we do differ between determenistic and random where it makes sense (as far as I know it should not have an impact on this specifc scenario, but if it does please let me know as well).

Which is meant to be used on a partial model that looks like this in .Net

public class Patient
{
    public ContactInformation ContactInformation { get; set; }
    public Demographic Demographic { get; set; }
}

public class ContactInformation
{
    public string PhoneNumber { get; set; }
}

public class Demographic
{
    public string? Title { get; set; } // nullable string
    public string FirstName { get; set; }
}

The main problem we are running into is the fact that certain properties can be possibly null if they are null they get added into the DB as null, which in turn causes the CSFLE to break

Now I have tried a variety of different options to build up the schema, including:

  • AnyOf →
{
  "contactInformation": {
    "bsonType": "object",
    "properties": {
      "phoneNumber": {
        "encrypt": {
          "bsonType": "string",
          "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random"
        }
      }
    }
  },
  "demographic": {
    "bsonType": "object",
    "properties": {
      "title": {
        "anyOf": [
          {
            "encrypt": {
              "bsonType": "string",
              "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random"
            }
          },
          {
            "bsonType": "null"
          }
        ]
      },
      "firstName": {
        "encrypt": {
          "bsonType": "string",
          "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random"
        }
      }
    }
  }
}

Or bsonTypeArray →

{
  "contactInformation": {
    "bsonType": "object",
    "properties": {
      "phoneNumber": {
        "encrypt": {
          "bsonType": "string",
          "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random"
        }
      }
    }
  },
  "demographic": {
    "bsonType": "object",
    "properties": {
      "title": {
            "encrypt": {
              "bsonType": ["string", "null"],
              "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random"
            }
          },
        ]
      },
      "firstName": {
        "encrypt": {
          "bsonType": "string",
          "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random"
        }
      }
    }
  }
}

None of the above options work

With Any of options, I get the following error:

Invalid schema containing the ‘encrypt’ keyword

Without the null options, I get the

Encryption-related exception: Command update failed: Cannot encrypt element of type: null.

The only “hack” we have found that works up until now is to basically remove all the null handling and manually force all null strings to be saved as empty string in the database, but this does not feel like the right solution long term especially as I am sure Mongo must have a mechanism to handle these null types in CSFLE schema

Any assistance on this would be greatly appreciated

1 Like

Hello and thanks for your post. I’m the Product Manager here at MongoDB for encryption. The encryption of null values is not supported. The reason is that encrypting nothing is undefined. If we were to do something like just store null values when the plaintext is null, that would clearly leak the null values, which could be useful information to an attacker, depending on the scenario.

1 Like

Is there a way to avoid the string and use an encryption schema that prevents null from the encryption. Do a pre encryption verification. If Null then, show invalid. Then move the object into into the encryption.

Can you expand on that a little bit? I think the best solution is to use a magic value to represent null. I don’t love that myself, but encrypting null is undefined. Be aware that if you use a magic value and need queryability, it would be MUCH better to choose Queryable Encryption over CSFLE because the only way CSFLE supports queryablity is with deterministic encryption, so it would be trivial to see which values in the database are null. Queryable Encryption would generate a new ciphertext for each encryption, so that information would be hidden.

1 Like

We also tried bsonType: ["string", "null"] and anyOf, same as you, none of it worked, Mongo throws schema errors. So for now, either skip the field if it’s null, or use empty strings as a workaround. Really hoping Mongo adds proper support for this down the line.