From 56beac8a4f96e05b2b8d2eced497f4f93bc62d28 Mon Sep 17 00:00:00 2001
From: Manuel Trezza <5673677+mtrezza@users.noreply.github.com>
Date: Fri, 12 Dec 2025 02:18:29 +0100
Subject: [PATCH 1/4] fix
---
DEPRECATIONS.md | 2 +-
spec/ParseQuery.spec.js | 22 +++++++++-------------
src/Deprecator/Deprecations.js | 1 -
src/Options/Definitions.js | 2 +-
src/Options/index.js | 2 +-
src/rest.js | 2 +-
6 files changed, 13 insertions(+), 18 deletions(-)
diff --git a/DEPRECATIONS.md b/DEPRECATIONS.md
index 6ac20b4616..a851c5d6fa 100644
--- a/DEPRECATIONS.md
+++ b/DEPRECATIONS.md
@@ -15,7 +15,7 @@ The following is a list of deprecations, according to the [Deprecation Policy](h
| DEPPS9 | Rename LiveQuery `fields` option to `keys` | [#8389](https://github.com/parse-community/parse-server/issues/8389) | 6.0.0 (2023) | 7.0.0 (2024) | removed | - |
| DEPPS10 | Encode `Parse.Object` in Cloud Function and remove option `encodeParseObjectInCloudFunction` | [#8634](https://github.com/parse-community/parse-server/issues/8634) | 6.2.0 (2023) | 9.0.0 (2026) | deprecated | - |
| DEPPS11 | Replace `PublicAPIRouter` with `PagesRouter` | [#7625](https://github.com/parse-community/parse-server/issues/7625) | 8.0.0 (2025) | 9.0.0 (2026) | deprecated | - |
-| DEPPS12 | Database option `allowPublicExplain` will default to `true` | [#7519](https://github.com/parse-community/parse-server/issues/7519) | 8.5.0 (2025) | 9.0.0 (2026) | deprecated | - |
+| DEPPS12 | Database option `allowPublicExplain` defaults to `true` | [#7519](https://github.com/parse-community/parse-server/issues/7519) | 8.5.0 (2025) | 9.0.0 (2026) | removed | - |
[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 0aa173dc65..4aa8e1bdee 100644
--- a/spec/ParseQuery.spec.js
+++ b/spec/ParseQuery.spec.js
@@ -5533,11 +5533,8 @@ describe('Parse.Query testing', () => {
);
it_id('c3d4e5f6-a7b8-4c9d-0e1f-2a3b4c5d6e7f')(it_only_db('mongo'))(
- 'explain works with and without master key by default',
+ 'explain requires master key by default',
async () => {
- const logger = require('../lib/logger').logger;
- const logSpy = spyOn(logger, 'warn').and.callFake(() => {});
-
await reconfigureServer({
databaseAdapter: undefined,
databaseURI: 'mongodb://localhost:27017/parse',
@@ -5546,21 +5543,20 @@ describe('Parse.Query testing', () => {
},
});
- // Verify deprecation warning is logged when allowPublicExplain is not explicitly set
- expect(logSpy).toHaveBeenCalledWith(
- jasmine.stringMatching(/DeprecationWarning.*databaseOptions\.allowPublicExplain.*false/)
- );
-
const obj = new TestObject({ foo: 'bar' });
await obj.save();
- // Without master key
+ // Without master key - should fail
const query = new Parse.Query(TestObject);
query.explain();
- const resultWithoutMasterKey = await query.find();
- expect(resultWithoutMasterKey).toBeDefined();
+ await expectAsync(query.find()).toBeRejectedWith(
+ new Parse.Error(
+ Parse.Error.INVALID_QUERY,
+ 'Using the explain query parameter requires the master key'
+ )
+ );
- // With master key
+ // With master key - should succeed
const queryWithMasterKey = new Parse.Query(TestObject);
queryWithMasterKey.explain();
const resultWithMasterKey = await queryWithMasterKey.find({ useMasterKey: true });
diff --git a/src/Deprecator/Deprecations.js b/src/Deprecator/Deprecations.js
index c63225f5b5..970364432b 100644
--- a/src/Deprecator/Deprecations.js
+++ b/src/Deprecator/Deprecations.js
@@ -18,5 +18,4 @@
module.exports = [
{ optionKey: 'encodeParseObjectInCloudFunction', changeNewDefault: 'true' },
{ optionKey: 'enableInsecureAuthAdapters', changeNewDefault: 'false' },
- { optionKey: 'databaseOptions.allowPublicExplain', changeNewDefault: 'false' },
];
diff --git a/src/Options/Definitions.js b/src/Options/Definitions.js
index 66c1d8bcea..37b55d65d7 100644
--- a/src/Options/Definitions.js
+++ b/src/Options/Definitions.js
@@ -1151,7 +1151,7 @@ module.exports.DatabaseOptions = {
help:
'Set to `true` to allow `Parse.Query.explain` without master key.
\u26A0\uFE0F Enabling this option may expose sensitive query performance data to unauthorized users and could potentially be exploited for malicious purposes.',
action: parsers.booleanParser,
- default: true,
+ default: false,
},
appName: {
env: 'PARSE_SERVER_DATABASE_APP_NAME',
diff --git a/src/Options/index.js b/src/Options/index.js
index cdeb7cd846..880a7b5917 100644
--- a/src/Options/index.js
+++ b/src/Options/index.js
@@ -754,7 +754,7 @@ export interface DatabaseOptions {
/* Set to `true` to disable validation of index fields. When disabled, indexes can be created even if the fields do not exist in the schema. This can be useful when creating indexes on fields that will be added later. */
disableIndexFieldValidation: ?boolean;
/* Set to `true` to allow `Parse.Query.explain` without master key.
⚠️ Enabling this option may expose sensitive query performance data to unauthorized users and could potentially be exploited for malicious purposes.
- :DEFAULT: true */
+ :DEFAULT: false */
allowPublicExplain: ?boolean;
/* An array of MongoDB client event configurations to enable logging of specific events. */
logClientEvents: ?(LogClientEvent[]);
diff --git a/src/rest.js b/src/rest.js
index 66763715ea..60ae4bd425 100644
--- a/src/rest.js
+++ b/src/rest.js
@@ -37,7 +37,7 @@ async function runFindTriggers(
const { isGet } = options;
if (restOptions && restOptions.explain && !auth.isMaster) {
- const allowPublicExplain = config.databaseOptions?.allowPublicExplain ?? true;
+ const allowPublicExplain = config.databaseOptions?.allowPublicExplain ?? false;
if (!allowPublicExplain) {
throw new Parse.Error(
From 23b8b7f5119a79c31c237562c322387ac646b0fb Mon Sep 17 00:00:00 2001
From: Manuel Trezza <5673677+mtrezza@users.noreply.github.com>
Date: Fri, 12 Dec 2025 02:24:17 +0100
Subject: [PATCH 2/4] test
---
spec/Deprecator.spec.js | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/spec/Deprecator.spec.js b/spec/Deprecator.spec.js
index 80e8632014..f5b6812699 100644
--- a/spec/Deprecator.spec.js
+++ b/spec/Deprecator.spec.js
@@ -47,7 +47,7 @@ describe('Deprecator', () => {
});
it('logs deprecation for nested option key with dot notation', async () => {
- deprecations = [{ optionKey: 'databaseOptions.allowPublicExplain', changeNewDefault: 'false' }];
+ deprecations = [{ optionKey: 'databaseOptions.testOption', changeNewDefault: 'false' }];
spyOn(Deprecator, '_getDeprecations').and.callFake(() => deprecations);
const logger = require('../lib/logger').logger;
@@ -60,14 +60,14 @@ describe('Deprecator', () => {
});
it('does not log deprecation for nested option key if option is set manually', async () => {
- deprecations = [{ optionKey: 'databaseOptions.allowPublicExplain', changeNewDefault: 'false' }];
+ deprecations = [{ optionKey: 'databaseOptions.testOption', changeNewDefault: 'false' }];
spyOn(Deprecator, '_getDeprecations').and.callFake(() => deprecations);
const logSpy = spyOn(Deprecator, '_logOption').and.callFake(() => {});
const Config = require('../lib/Config');
const config = Config.get('test');
// Directly test scanParseServerOptions with nested option set
- Deprecator.scanParseServerOptions({ databaseOptions: { allowPublicExplain: true } });
+ Deprecator.scanParseServerOptions({ databaseOptions: { testOption: true } });
expect(logSpy).not.toHaveBeenCalled();
});
});
From 16ac26bf2d0e7c2c93bfa5e7444c17c29dcf56c2 Mon Sep 17 00:00:00 2001
From: Manuel Trezza <5673677+mtrezza@users.noreply.github.com>
Date: Fri, 12 Dec 2025 02:32:03 +0100
Subject: [PATCH 3/4] test
---
spec/ParseQuery.spec.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/spec/ParseQuery.spec.js b/spec/ParseQuery.spec.js
index 4aa8e1bdee..4dd7eaecea 100644
--- a/spec/ParseQuery.spec.js
+++ b/spec/ParseQuery.spec.js
@@ -5369,7 +5369,7 @@ describe('Parse.Query testing', () => {
const query = new Parse.Query('_User');
query.equalTo('objectId', user.id);
query.explain();
- const result = await query.find();
+ const result = await query.find({ useMasterKey: true });
// Validate
expect(result.executionStats).not.toBeUndefined();
});
From 0c5b790453e28b5d690a1447903c04d830dc49c0 Mon Sep 17 00:00:00 2001
From: Manuel Trezza <5673677+mtrezza@users.noreply.github.com>
Date: Fri, 12 Dec 2025 02:40:40 +0100
Subject: [PATCH 4/4] Update DEPRECATIONS.md
---
DEPRECATIONS.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/DEPRECATIONS.md b/DEPRECATIONS.md
index a851c5d6fa..530916cfef 100644
--- a/DEPRECATIONS.md
+++ b/DEPRECATIONS.md
@@ -15,7 +15,7 @@ The following is a list of deprecations, according to the [Deprecation Policy](h
| DEPPS9 | Rename LiveQuery `fields` option to `keys` | [#8389](https://github.com/parse-community/parse-server/issues/8389) | 6.0.0 (2023) | 7.0.0 (2024) | removed | - |
| DEPPS10 | Encode `Parse.Object` in Cloud Function and remove option `encodeParseObjectInCloudFunction` | [#8634](https://github.com/parse-community/parse-server/issues/8634) | 6.2.0 (2023) | 9.0.0 (2026) | deprecated | - |
| DEPPS11 | Replace `PublicAPIRouter` with `PagesRouter` | [#7625](https://github.com/parse-community/parse-server/issues/7625) | 8.0.0 (2025) | 9.0.0 (2026) | deprecated | - |
-| DEPPS12 | Database option `allowPublicExplain` defaults to `true` | [#7519](https://github.com/parse-community/parse-server/issues/7519) | 8.5.0 (2025) | 9.0.0 (2026) | removed | - |
+| DEPPS12 | Database option `allowPublicExplain` defaults to `false` | [#7519](https://github.com/parse-community/parse-server/issues/7519) | 8.5.0 (2025) | 9.0.0 (2026) | removed | - |
[i_deprecation]: ## "The version and date of the deprecation."
[i_removal]: ## "The version and date of the planned removal."