Uploaded image for project: 'Core Server'
  1. Core Server
  2. SERVER-69946

QE upsert excludes encrypted field in filter

    XMLWordPrintableJSON

Details

    • Server Security
    • ALL
    • Hide

      A full repro is included here: https://github.com/kevinAlbs/go-bootstrap/blob/418081b2e33688c8d88f47a1fecb75beceefc042/csfle/qe_updateOne/main.go

      It runs an UpdateOne operation to upsert a new document. A Queryable Encryption (QE) field "encryptedIndexed" is included in the filter.

      filter := bson.M{"_id": 1, "encryptedIndexed": "foo"}
      update := bson.M{"$set": bson.M{"foo": "bar"}}
      opts := options.Update().SetUpsert(true)
      _, err = encryptedColl.UpdateOne(context.Background(),
      	filter,
      	update,
      	opts)
      

      Results in an upsert of the document:

      {"_id":{"$numberInt":"1"},"foo":"bar"}
      

      The expectation is for the document to include "encryptedIndexed".

      The full update command sent is the following:

      {
      	"update": "encrypted",
      	"ordered": true,
      	"updates": [
      	  {
      		"q": {
      		  "$and": [
      			{
      			  "_id": {
      				"$eq": {
      				  "$numberInt": "1"
      				}
      			  }
      			},
      			{
      			  "encryptedIndexed": {
      				"$eq": {
      				  "$binary": {
      					"base64": "BbEAAAAFZAAgAAAAAL7xGjpBxVi9AIH0MXbRGg9CYPzd42r9XjYcg8n5x9+zBXMAIAAAAAAMK7nVUWqB0CwpzVUMD4wmLn8yiKFvR9blOXKsSiHmRQVjACAAAAAActpJSZdO05aQQMFx5GQnrJcFbWFSx920vVpl6EebLqEFZQAgAAAAAE+1+k92587YImwuJWd/+080s+4IJmCobZoQjRHTTk8xEmNtAAAAAAAAAAAAAA==",
      					"subType": "06"
      				  }
      				}
      			  }
      			}
      		  ]
      		},
      		"u": {
      		  "$set": {
      			"foo": "bar"
      		  }
      		},
      		"multi": false,
      		"upsert": true
      	  }
      	],
      	"encryptionInformation": {
      	  "type": {
      		"$numberInt": "1"
      	  },
      	  "schema": {
      		"db.encrypted": {
      		  "escCollection": "enxcol_.encrypted.esc",
      		  "eccCollection": "enxcol_.encrypted.ecc",
      		  "ecocCollection": "enxcol_.encrypted.ecoc",
      		  "fields": [
      			{
      			  "keyId": {
      				"$binary": {
      				  "base64": "Pn4gGwr/Rq638KyxGcBpoA==",
      				  "subType": "04"
      				}
      			  },
      			  "path": "encryptedIndexed",
      			  "bsonType": "string",
      			  "queries": {
      				"queryType": "equality",
      				"contention": {
      				  "$numberLong": "0"
      				}
      			  }
      			}
      		  ]
      		}
      	  },
      	  "deleteTokens": {
      		"db.encrypted": {
      		  "encryptedIndexed": {
      			"e": {
      			  "$binary": {
      				"base64": "T7X6T3bnztgibC4lZ3/7TzSz7ggmYKhtmhCNEdNOTzE=",
      				"subType": "00"
      			  }
      			},
      			"o": {
      			  "$binary": {
      				"base64": "wVFp0gQ3odC1Mohr8UQ/RRlYrAjnu8kiXPgsawE0wpU=",
      				"subType": "00"
      			  }
      			}
      		  }
      		}
      	  }
      	},
      	"lsid": {
      	  "id": {
      		"$binary": {
      		  "base64": "hn5Jvj/zQEezCP8t5NbIGQ==",
      		  "subType": "04"
      		}
      	  }
      	},
      	"txnNumber": {
      	  "$numberLong": "1"
      	},
      	"$clusterTime": {
      	  "clusterTime": {
      		"$timestamp": {
      		  "t": 1663944792,
      		  "i": 3
      		}
      	  },
      	  "signature": {
      		"hash": {
      		  "$binary": {
      			"base64": "AAAAAAAAAAAAAAAAAAAAAAAAAAA=",
      			"subType": "00"
      		  }
      		},
      		"keyId": {
      		  "$numberLong": "0"
      		}
      	  }
      	},
      	"$db": "db"
        }
      

      Show
      A full repro is included here: https://github.com/kevinAlbs/go-bootstrap/blob/418081b2e33688c8d88f47a1fecb75beceefc042/csfle/qe_updateOne/main.go It runs an UpdateOne operation to upsert a new document. A Queryable Encryption (QE) field "encryptedIndexed" is included in the filter. filter := bson.M{"_id": 1, "encryptedIndexed": "foo"} update := bson.M{"$set": bson.M{"foo": "bar"}} opts := options.Update().SetUpsert(true) _, err = encryptedColl.UpdateOne(context.Background(), filter, update, opts) Results in an upsert of the document: {"_id":{"$numberInt":"1"},"foo":"bar"} The expectation is for the document to include "encryptedIndexed". The full update command sent is the following: { "update": "encrypted", "ordered": true, "updates": [ { "q": { "$and": [ { "_id": { "$eq": { "$numberInt": "1" } } }, { "encryptedIndexed": { "$eq": { "$binary": { "base64": "BbEAAAAFZAAgAAAAAL7xGjpBxVi9AIH0MXbRGg9CYPzd42r9XjYcg8n5x9+zBXMAIAAAAAAMK7nVUWqB0CwpzVUMD4wmLn8yiKFvR9blOXKsSiHmRQVjACAAAAAActpJSZdO05aQQMFx5GQnrJcFbWFSx920vVpl6EebLqEFZQAgAAAAAE+1+k92587YImwuJWd/+080s+4IJmCobZoQjRHTTk8xEmNtAAAAAAAAAAAAAA==", "subType": "06" } } } } ] }, "u": { "$set": { "foo": "bar" } }, "multi": false, "upsert": true } ], "encryptionInformation": { "type": { "$numberInt": "1" }, "schema": { "db.encrypted": { "escCollection": "enxcol_.encrypted.esc", "eccCollection": "enxcol_.encrypted.ecc", "ecocCollection": "enxcol_.encrypted.ecoc", "fields": [ { "keyId": { "$binary": { "base64": "Pn4gGwr/Rq638KyxGcBpoA==", "subType": "04" } }, "path": "encryptedIndexed", "bsonType": "string", "queries": { "queryType": "equality", "contention": { "$numberLong": "0" } } } ] } }, "deleteTokens": { "db.encrypted": { "encryptedIndexed": { "e": { "$binary": { "base64": "T7X6T3bnztgibC4lZ3/7TzSz7ggmYKhtmhCNEdNOTzE=", "subType": "00" } }, "o": { "$binary": { "base64": "wVFp0gQ3odC1Mohr8UQ/RRlYrAjnu8kiXPgsawE0wpU=", "subType": "00" } } } } } }, "lsid": { "id": { "$binary": { "base64": "hn5Jvj/zQEezCP8t5NbIGQ==", "subType": "04" } } }, "txnNumber": { "$numberLong": "1" }, "$clusterTime": { "clusterTime": { "$timestamp": { "t": 1663944792, "i": 3 } }, "signature": { "hash": { "$binary": { "base64": "AAAAAAAAAAAAAAAAAAAAAAAAAAA=", "subType": "00" } }, "keyId": { "$numberLong": "0" } } }, "$db": "db" }
    • Security 2022-10-03, Security 2022-10-17

    Description

      Upserting a document to a collection with Queryable Encryption excludes the encrypted field from the filter.

      For example:

      filter := bson.M{"_id": 1, "encryptedIndexed": "foo"}
      update := bson.M{"$set": bson.M{"foo": "bar"}}
      opts := options.Update().SetUpsert(true)
      _, err = encryptedColl.UpdateOne(context.Background(),
      	filter,
      	update,
      	opts)
      

      Results in an upsert of the document:

      {"_id":{"$numberInt":"1"},"foo":"bar"}
      

      Attachments

        Activity

          People

            backlog-server-security Backlog - Security Team
            kevin.albertson@mongodb.com Kevin Albertson
            Votes:
            0 Vote for this issue
            Watchers:
            7 Start watching this issue

            Dates

              Created:
              Updated: