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

QE upsert excludes encrypted field in filter

    • 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

      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"}
      

            Assignee:
            backlog-server-security [DO NOT USE] Backlog - Security Team
            Reporter:
            kevin.albertson@mongodb.com Kevin Albertson
            Votes:
            0 Vote for this issue
            Watchers:
            7 Start watching this issue

              Created:
              Updated: