[SERVER-10695] Redact pipeline: Subobject without security markings causes aggregate to fail Created: 06/Sep/13  Updated: 10/Dec/14  Resolved: 13/Sep/13

Status: Closed
Project: Core Server
Component/s: Aggregation Framework
Affects Version/s: 2.5.2
Fix Version/s: None

Type: Bug Priority: Major - P3
Reporter: David Erickson Assignee: Matt Dannenberg
Resolution: Done Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified
Environment:

Mac OS X, MongoDB 2.5.2


Operating System: OS X
Steps To Reproduce:

t = db.redact_tests;
t.drop();

t.save({
_id: 1,
sl: [["GroupA"], ["GroupA", "GroupB"]],

text: "A or B Can see this",

subObjectWithSL:

{ sl: [["GroupB"]], text: "Only B can see this" }

,

anotherSubObjectWithSL:

{ sl: [["GroupA"]], text: "All users with doc access can see this" }

,

/* subObjectWithoutSL:

{ text: "This blows up the redactor when uncommented" }

*/

arrayWithUnMarkedSubObjects: [

{sl:[["GroupA"]], text: "I can see this"}

,
//

{text: "This blows up the redactor when uncommented"}

,
"Not an object"
]
});

t.aggregate([
{$redact:{ $cond: [
{$any:[
{
$map: {
input: "$sl",
as: "setNeeded",
in:

{ $setIsSubset: ["$$setNeeded", ["GroupA", "GroupB"]] }

}
}
]},
"$$CONTINUE",
"$$PRUNE"
]}}
]);

Participants:

 Description   

If a subobject, whether or not it is in an array does not contain the field that we are checking for in a $redact using the $any operator, the aggregate command returns an error.

To see the problem, uncomment lines from the "Steps To Reproduce sections"

Error: Printing Stack Trace
at printStackTrace (src/mongo/shell/utils.js:37:15)
at DBCollection.aggregate (src/mongo/shell/collection.js:927:9)
at (shell):1:3
2013-09-06T11:49:43.683-0400 aggregate failed: {
"errmsg" : "exception: $any's argument must be an array, but is NULL",
"code" : 17041,
"ok" : 0
} at src/mongo/shell/collection.js:928

This is contrary to the behavior implied in the jstests where there are subobjects without the "level" key (see the f: in the subobject). Probably because that $redact doesn't use $any in its condition
https://github.com/mongodb/mongo/blob/master/jstests/aggregation/bugs/server8581.js

d: [

{level: 1, e: 4}

,

{f: 6}

,

{level: 5, g: 9}

,
"NOT AN OBJECT!!11!" // always included when b is included
]



 Comments   
Comment by David Erickson [ 13/Sep/13 ]

This does indeed work in the situation where not all subobjects in the data model have markings. Thanks!

Comment by Matt Dannenberg [ 12/Sep/13 ]

I was able to get the command to work as expected by changing your aggregation command to handle the null and replace it with an empty array (using $ifNull), does this fix work for you as well?

t.aggregate([
{$redact:{ $cond: [
{$any:[
{
$map: {
input: {$ifNull:["$sl",[[]]]},
as: "setNeeded",
in:

{ $setIsSubset: [ "$$setNeeded", ["GroupA", "GroupB"]] }

}
}
]},
"$$CONTINUE",
"$$PRUNE"
]}}
]);

I had to have $ifNull return an empty array containing an empty array instead of just an empty array. This is because $map expects an array and each entry of dollar map gets passed to $setIsSubset, which also expects an empty array.

Generated at Thu Feb 08 03:23:49 UTC 2024 using Jira 9.7.1#970001-sha1:2222b88b221c4928ef0de3161136cc90c8356a66.