[fix][core] restrict export projections to include and exclude - #7945
Open
ar2rsawseen wants to merge 1 commit into
Open
[fix][core] restrict export projections to include and exclude#7945ar2rsawseen wants to merge 1 commit into
ar2rsawseen wants to merge 1 commit into
Conversation
/o/export/db parses the caller's projection and hands it to find() as given. MongoDB 4.4
and later evaluate aggregation expressions in a find projection, so a value like
{"pw": "$password"} renames a field rather than selecting one, and the credential redaction
that runs afterwards removes fields by name. A renamed field therefore carries its value
into the export under a name the redaction does not know. The same applies to computed
expressions, and $function evaluates javascript inside the database engine.
The DB Viewer already guarded its own projections for exactly this reason, and its comment
names the vector. That guard was never applied to the export path, even though the commit
that added the export redaction set out to align the two.
Move the guard into api/utils/common.js so there is one implementation, have the DB Viewer
helper delegate to it, and apply it to the export path after the projection is parsed.
Plain include and exclude are untouched, which is everything the dashboard sends: the
datatable exports pass field lists of 0 and 1.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
/o/export/dbparses the caller'sprojectionand passes it tofind()unchanged:MongoDB 4.4 and later evaluate aggregation expressions in a find projection, so a value can rename or compute a field rather than select one. The credential redaction that runs on the cursor removes fields by name, so a renamed field carries its value into the export file under a name the redaction does not know about.
Measured against MongoDB 7.0.37, all of these are accepted by
find()and return the underlying values:{"pw": "$password", "ak": "$api_key", "tfa": "$two_factor_auth"}{"secret": "$two_factor_auth.secret_token"}{"both": {"$concat": ["$password", "$api_key"]}}{"x": {"$function": {"body": "...", "lang": "js"}}}The DB Viewer already guarded its own projections for this exact reason, and its comment names the vector, including the
$functioncase. The guard was never applied to the export path, although the commit that added the export redaction set out to align the two.Change
common.sanitizeProjectioninapi/utils/common.js: one implementation, restricting a projection to0,1,trueandfalse.plugins/dbviewer/api/parts/query_guard.jsdelegates to it, so the DB Viewer and the export cannot drift apart again.Scope
Every place a caller influenced projection can reach a database, across the three repositories:
/o/export/db->exports.fromDatabase->find(query, {projection})/o/export/request->exports.fromRequestplugins/views$projectpipelinesplugins/surveysaggregationoptions.projectNot changed, on purpose
sortandformatFieldson the same handler are also parsed from the request. A sort value is not an expression context in the same way, and the dashboard sends real sort objects, so tightening them here would risk breaking exports for no security gain.plugins/dbviewer/api/api.js) takes a caller supplied object into a ClickHouse query builder. Mongo style expressions do not apply there, so this guard is not the right tool, and whether that builder is safe with arbitrary keys is a separate question worth its own look rather than a change made in passing.Verification
test/unit-tests/api.utils.common.jsgains 6 cases: plain include and exclude survive untouched, field path aliases and nested aliases are dropped,$concat,$functionand$condare dropped, invalid values such as2,NaNand strings are dropped, and a missing or non object projection is handled. Replacing the guard with a pass through fails 4 of them.release.24.05three unrelated cases in that file already fail on stock (mongodb.ObjectID is not a function, a driver artifact). The 6 added cases pass there.