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

mongocryptd can fail to produce an intent-to-encrypt marking for $redact

    XMLWordPrintable

    Details

    • Type: Bug
    • Status: Closed
    • Priority: Critical - P2
    • Resolution: Gone away
    • Affects Version/s: None
    • Fix Version/s: None
    • Component/s: Querying
    • Operating System:
      ALL
    • Backport Requested:
      v4.2
    • Steps To Reproduce:
      Hide

      Run the following script against mongocryptd:

      const jsonSchema = {
          type: "object",
          properties: {
              user: {
                  type: "object",
                  properties: {
                      ssn: {
                          encrypt: {
                              algorithm: "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic",
                              keyId: [UUID()],
                              bsonType: "string"
                          }
                      }
                  }
              }
          }
      };
       
      const pipeline =
          [{$redact: {$cond: {if: {$eq: ["$ssn", "123-45-6789"]}, then: "$$PRUNE", else: "$$DESCEND"}}}];
       
      printjson(db.runCommand({
          aggregate: "c",
          pipeline: pipeline,
          cursor: {},
          isRemoteSchema: false,
          jsonSchema: jsonSchema
      }));
      

      This produces the following output:

      {
      	"hasEncryptionPlaceholders" : false,
      	"schemaRequiresEncryption" : true,
      	"result" : {
      		"aggregate" : "c",
      		"pipeline" : [
      			{
      				"$redact" : {
      					"$cond" : [
      						{
      							"$eq" : [
      								"$ssn",
      								{
      									"$const" : "123-45-6789"
      								}
      							]
      						},
      						"$$PRUNE",
      						"$$DESCEND"
      					]
      				}
      			}
      		],
      		"cursor" : {
       
      		},
      		"lsid" : {
      			"id" : UUID("0506dff3-cdf4-4dde-afb3-d31221391d45")
      		}
      	},
      	"ok" : 1
      }
      

      The important thing to note is that the social security number in the query is not marked for encryption. The system would send it across the wire as plaintext.

      Since it is possible for the SSN in the query to be compared both to encrypted and unencrypted data, the correct behavior would be for mongocryptd to return an error.

      Show
      Run the following script against mongocryptd: const jsonSchema = { type: "object", properties: { user: { type: "object", properties: { ssn: { encrypt: { algorithm: "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic", keyId: [UUID()], bsonType: "string" } } } } } };   const pipeline = [{$redact: {$cond: {if: {$eq: ["$ssn", "123-45-6789"]}, then: "$$PRUNE", else: "$$DESCEND"}}}];   printjson(db.runCommand({ aggregate: "c", pipeline: pipeline, cursor: {}, isRemoteSchema: false, jsonSchema: jsonSchema })); This produces the following output: { "hasEncryptionPlaceholders" : false, "schemaRequiresEncryption" : true, "result" : { "aggregate" : "c", "pipeline" : [ { "$redact" : { "$cond" : [ { "$eq" : [ "$ssn", { "$const" : "123-45-6789" } ] }, "$$PRUNE", "$$DESCEND" ] } } ], "cursor" : {   }, "lsid" : { "id" : UUID("0506dff3-cdf4-4dde-afb3-d31221391d45") } }, "ok" : 1 } The important thing to note is that the social security number in the query is not marked for encryption. The system would send it across the wire as plaintext. Since it is possible for the SSN in the query to be compared both to encrypted and unencrypted data, the correct behavior would be for mongocryptd to return an error.
    • Sprint:
      Query 2019-07-01

      Description

      In SERVER-40832 we added client-side encryption support for the $redact aggregation stage. This works by simply calling into our regular aggregation expression analysis which marks agg expressions for encryption. This so intent-to-encrypt marking logic, however, always assumes that field paths are full paths with respect to $$ROOT. It does not account for the fact that during $redact's descent of an object, $$CURRENT is rebound such that $$CURRENT != $$ROOT. Therefore, field paths in $redact are not always full path starting from the root of the document. The consequence is that the analysis can fail to mark a constant for encryption. See "Steps to Reproduce" for an example.

      A quick fix for this problem would be to revert the changes in SERVER-40832. As a more complex fix, we could investigate whether it is possible to handle special cases in which we can statically prove that it is impossible for a comparison made in $redact to happen against both encrypted and unencrypted data.

        Attachments

          Issue Links

            Activity

              People

              Assignee:
              arun.banala Arun Banala
              Reporter:
              david.storch David Storch
              Participants:
              Votes:
              0 Vote for this issue
              Watchers:
              2 Start watching this issue

                Dates

                Created:
                Updated:
                Resolved: