spring-projects / spring-projects/spring-data-mongodb

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

Open
#3,888 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

type: enhancement
Dominant language
Java
Stars
1.7k
Forks
1.1k
PR merge metrics
No merged PRs in 30d

Description

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).

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with MongoJsonSchemaCreator.encryptedOnly() and the provided testCollectionSchema reproduction using Company, Person, and a List. Verify the generated schema against MongoDB's CSFLE restriction, then add coverage showing that collection elements with encrypted fields do not produce an invalid encrypt keyword under items.

Written by the indexing model from the issue text.

Assessment

Tech stack
java, mongodb
Domain
databases
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.