Skip to content

MongoJsonSchemaCreator with encryptedOnly filter generates invalid schema when using collections of objects with encrypted fields #3888

@Pastissad

Description

@Pastissad

Hello,

According to the MongoDB automatic CSFLE specs (https://docs.mongodb.com/manual/reference/security-client-side-automatic-json-schema/#std-label-field-level-encryption-encrypt-keyword) :

encrypt cannot be specified within any subschema of the items or additionalItems keywords. Specifically, automatic client-side field level encryption does not support encrypting individual elements of an array.

However, the MongoJsonSchemaCreator::encryptedOnly filter provided to generate Mongo's encryption schema generates a schema with encryption configuration in the subschema of collections' "items" node when encountering a collection of objects containing an @Encrypted annotation.

Exemple :

@Test
public void testCollectionSchema() {
    final MongoMappingContext mappingContext = new MongoMappingContext();
    mappingContext.setSimpleTypeHolder(MongoSimpleTypes.HOLDER);
    mappingContext.setInitialEntitySet(Set.of(Company.class));
    mappingContext.afterPropertiesSet();

    final MappingMongoConverter converter = new MappingMongoConverter(NoOpDbRefResolver.INSTANCE, mappingContext);
    converter.setCustomConversions(MongoCustomConversions.create(config -> { }));
    converter.afterPropertiesSet();

    final MongoJsonSchemaCreator mongoJsonSchemaCreator = MongoJsonSchemaCreator.create(converter).filter(MongoJsonSchemaCreator.encryptedOnly());

    final MongoJsonSchema companySchema = mongoJsonSchemaCreator.createSchemaFor(Company.class);
    final String jsonSchema = companySchema.schemaDocument().toJson();
}

@Data
static class Company {
    private Person ceo;
    private List<Person> employees;
}

@Data
static class Person {
    @Encrypted
    String name;
}

Will generate this schema :

{
	"type": "object",
	"properties": {
		"ceo": {
			"type": "object",
			"properties": {
				"name": {
					"encrypt": {
						"bsonType": "string",
						"algorithm": null
					}
				}
			}
		},
		"employees": {
			"type": "array",
			"items": {
				"type": "object",
				"properties": {
					"name": {
						"encrypt": {
							"bsonType": "string",
							"algorithm": null
						}
					}
				}
			}
		}
	}
}

The "employees" node is invalid as the generated schema includes encryption inside an 'items' subschema.

This schema generates an error in mongo client at runtime on any command executed :

com.mongodb.MongoCommandException: Command failed with error 51077 (Location51077): 'Invalid schema containing the 'encrypt' keyword.' on server xxx:yyy. The full response is {"ok": 0.0, "errmsg": "Invalid schema containing the 'encrypt' keyword.", "code": 51077, "codeName": "Location51077"}

I'd expect the filter to filter out any collection from the schema when not directly annotated with @Encrypted (full collection encryption, which is sadly the only supported way by CSFLE for those).

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions