From 2359f6ee02f53d3e004c37827b9552e980c078d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kartal=20Kaan=20Bozdo=C4=9Fan?= Date: Tue, 24 Aug 2021 14:38:52 +0200 Subject: [PATCH 1/2] Explain queries run by non-master users now print a runtime deprecation warning Added pending tests that ensure non-master users cannot run explain queries Added the change to the CHANGELOG --- CHANGELOG.md | 1 + DEPRECATIONS.md | 1 + spec/ParseQuery.spec.js | 32 ++++++++++++++++++++++++++++++++ src/rest.js | 13 +++++++++++++ 4 files changed, 47 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index d96ee3d959..bc2c470d2b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -108,6 +108,7 @@ ___ - Added Deprecation Policy to govern the introduction of breaking changes in a phased pattern that is more predictable for developers (Manuel Trezza) [#7199](https://github.com/parse-community/parse-server/pull/7199) - Add REST API endpoint `/loginAs` to create session of any user with master key; allows to impersonate another user. (GormanFletcher) [#7406](https://github.com/parse-community/parse-server/pull/7406) - Add official support for MongoDB 5.0 (Manuel Trezza) [#7469](https://github.com/parse-community/parse-server/pull/7469) +- Deprecated ``explain` queries run by non-master users (Kartal Kaan Bozdogan) [#7519](https://github.com/parse-community/parse-server/issues/7519) ### Other Changes - Support native mongodb syntax in aggregation pipelines (Raschid JF Rafeally) [#7339](https://github.com/parse-community/parse-server/pull/7339) diff --git a/DEPRECATIONS.md b/DEPRECATIONS.md index cf220a0054..8fc2be0925 100644 --- a/DEPRECATIONS.md +++ b/DEPRECATIONS.md @@ -6,6 +6,7 @@ The following is a list of deprecations, according to the [Deprecation Policy](h |-------------------------------------------------|----------------------------------------------------------------------|---------------------------------|---------------------------------|-----------------------|-------| | Native MongoDB syntax in aggregation pipeline | [#7338](https://github.com/parse-community/parse-server/issues/7338) | 5.0.0 (2022) | 6.0.0 (2023) | deprecated | - | | Config option `directAccess` defaults to `true` | [#6636](https://github.com/parse-community/parse-server/pull/6636) | 5.0.0 (2022) | 6.0.0 (2023) | deprecated | - | +| `explain` queries used by non-master users | [#7519](https://github.com/parse-community/parse-server/issues/7519) | XXX | XXX | deprecated | - | [i_deprecation]: ## "The version and date of the deprecation." [i_removal]: ## "The version and date of the planned removal." diff --git a/spec/ParseQuery.spec.js b/spec/ParseQuery.spec.js index e196280a5c..cc77bab7a9 100644 --- a/spec/ParseQuery.spec.js +++ b/spec/ParseQuery.spec.js @@ -5218,4 +5218,36 @@ describe('Parse.Query testing', () => { // Validate expect(result.executionStats).not.toBeUndefined(); }); + + xit('users cannot use explain queries', async () => { + // Create an object + const obj = new TestObject({ foo: 'baz', hello: 'world' }); + await obj.save(); + // Query TestObject with explain. + const query = new Parse.Query('TestObject'); + query.equalTo('objectId', obj.id); + query.explain(); + try { + await query.find(); + fail('even non-master users can use explain'); + } catch (e) { + equal(e.code, Parse.Error.OPERATION_FORBIDDEN); + equal(e.message, 'Cannot explain'); + } + try { + await new Parse.Query('TestObject').explain().get(obj.id); + fail('even non-master users can use explain'); + } catch (e) { + equal(e.code, Parse.Error.OPERATION_FORBIDDEN); + equal(e.message, 'Cannot explain'); + } + }).pend('Disabled until non-master explains are disabled'); + it('the master key can use explain queries', async () => { + const obj = new TestObject({ foo: 'baz', hello: 'world' }); + await obj.save(); + const query = new Parse.Query('TestObject'); + query.equalTo('objectId', obj.id); + query.explain(); + await query.find({ useMasterKey: true }); // Must not throw + }); }); diff --git a/src/rest.js b/src/rest.js index fca3497a5d..4f7dbbdebc 100644 --- a/src/rest.js +++ b/src/rest.js @@ -12,6 +12,7 @@ var Parse = require('parse/node').Parse; var RestQuery = require('./RestQuery'); var RestWrite = require('./RestWrite'); var triggers = require('./triggers'); +import Deprecator from './Deprecator/Deprecator'; function checkTriggers(className, config, types) { return types.some(triggerType => { @@ -26,6 +27,12 @@ function checkLiveQuery(className, config) { // Returns a promise for an object with optional keys 'results' and 'count'. function find(config, auth, className, restWhere, restOptions, clientSDK, context) { enforceRoleSecurity('find', className, auth); + if (restOptions && restOptions.explain && !auth.isMaster) { + //throw new Parse.Error(Parse.Error.OPERATION_FORBIDDEN, 'Cannot explain'); + Deprecator.logRuntimeDeprecation({ + usage: 'The use of explain queries by non-master users', + }); + } return triggers .maybeRunQueryTrigger( triggers.Types.beforeFind, @@ -57,6 +64,12 @@ function find(config, auth, className, restWhere, restOptions, clientSDK, contex const get = (config, auth, className, objectId, restOptions, clientSDK, context) => { var restWhere = { objectId }; enforceRoleSecurity('get', className, auth); + if (restOptions && restOptions.explain && !auth.isMaster) { + //throw new Parse.Error(Parse.Error.OPERATION_FORBIDDEN, 'Cannot explain'); + Deprecator.logRuntimeDeprecation({ + usage: 'The use of explain queries by non-master users', + }); + } return triggers .maybeRunQueryTrigger( triggers.Types.beforeFind, From b9e27069d3104f136ac53e030c7d81db2108031b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kartal=20Kaan=20Bozdo=C4=9Fan?= Date: Wed, 25 Aug 2021 11:56:03 +0200 Subject: [PATCH 2/2] Add deprecation version number --- DEPRECATIONS.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DEPRECATIONS.md b/DEPRECATIONS.md index 8fc2be0925..7be8a285eb 100644 --- a/DEPRECATIONS.md +++ b/DEPRECATIONS.md @@ -6,7 +6,7 @@ The following is a list of deprecations, according to the [Deprecation Policy](h |-------------------------------------------------|----------------------------------------------------------------------|---------------------------------|---------------------------------|-----------------------|-------| | Native MongoDB syntax in aggregation pipeline | [#7338](https://github.com/parse-community/parse-server/issues/7338) | 5.0.0 (2022) | 6.0.0 (2023) | deprecated | - | | Config option `directAccess` defaults to `true` | [#6636](https://github.com/parse-community/parse-server/pull/6636) | 5.0.0 (2022) | 6.0.0 (2023) | deprecated | - | -| `explain` queries used by non-master users | [#7519](https://github.com/parse-community/parse-server/issues/7519) | XXX | XXX | deprecated | - | +| `explain` queries used by non-master users | [#7519](https://github.com/parse-community/parse-server/issues/7519) | 5.0.0 (2022) | 6.0.0 (2023) | deprecated | - | [i_deprecation]: ## "The version and date of the deprecation." [i_removal]: ## "The version and date of the planned removal."