fix: LiveQuery protected-field guard bypass via array-like logical operator value (GHSA-mmg8-87c5-jrc2)#10350
Conversation
|
🚀 Thanks for opening this pull request! We appreciate your effort in improving the project. Please let us know once your pull request is ready for review. Tip
Note Please respond to review comments from AI agents just like you would to comments from a human reviewer. Let the reviewer resolve their own comments, unless they have reviewed and accepted your commit, or agreed with your explanation for why the feedback was incorrect. Caution Pull requests must be written using an AI agent with human supervision. Pull requests written entirely by a human will likely be rejected, because of lower code quality, higher review effort and the higher risk of introducing bugs. Please note that AI review comments on this pull request alone do not satisfy this requirement. |
✅ Snyk checks have passed. No issues have been found so far.
💻 Catch issues earlier using the plugins for VS Code, JetBrains IDEs, Visual Studio, and Eclipse. |
📝 WalkthroughWalkthroughAdds strict array-type validation for Changes
Sequence Diagram(s)sequenceDiagram
participant Client as Client
participant LQ as ParseLiveQueryServer
participant Tools as QueryTools / RestQuery
participant DB as Database
Client->>LQ: subscribe(query with $or/$and/$nor)
LQ->>Tools: _validateQueryConstraints(where)
Tools-->>LQ: invalid if operator present && not Array
alt invalid operator type
LQ-->>Client: reject with Parse.Error.INVALID_QUERY
else valid arrays
LQ->>DB: evaluate subscription / perform protected-field traversal
DB-->>LQ: results / no matching events if denied
LQ-->>Client: subscription established (or rejected if protected fields found)
end
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related PRs
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
spec/vulnerabilities.spec.js (1)
5335-5373: Add the matching REST regression for these malformed operators.These cases only exercise
query.subscribe(), but the fix also hardens the HTTP query path. A/classes/SecretClassregression with the same array-like$or/$and/$norpayloads would keep the REST and LiveQuery validators from drifting independently.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@spec/vulnerabilities.spec.js` around lines 5335 - 5373, Add REST regression tests mirroring the LiveQuery cases by issuing POST requests to the classes endpoint (e.g., POST to /classes/SecretClass) with the same malformed array-like $or/$and/$nor payloads used in the subscribe tests and asserting the server returns a Parse.Error.INVALID_QUERY (HTTP 400) for each payload; reference the existing test patterns that use Parse.Query and query.subscribe() and replicate them by constructing the equivalent {"where": { $or: { "0": {...}, length: 1 } }} (and similar for $and/$nor and the non-protected-field $or) in the REST request body so the REST query path is validated the same as the LiveQuery path.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@spec/vulnerabilities.spec.js`:
- Around line 5375-5401: The test currently wraps the entire subscription flow
in one try/catch so any later error (like obj.save() or the updateSpy assertion)
can be mistaken for the subscribe() rejection; change the logic to only catch
the subscribe() call itself by invoking await query.subscribe() inside its own
try/catch (assign to a local subscription variable on success and set
subscriptionError only from that catch), then run the rest of the interaction
(subscription.on handlers, obj.set()/obj.save(), assertions) outside that catch
so failures there do not mark subscribe() as rejected; reference:
query.subscribe(), subscriptionError, subscription, updateSpy, obj.save().
---
Nitpick comments:
In `@spec/vulnerabilities.spec.js`:
- Around line 5335-5373: Add REST regression tests mirroring the LiveQuery cases
by issuing POST requests to the classes endpoint (e.g., POST to
/classes/SecretClass) with the same malformed array-like $or/$and/$nor payloads
used in the subscribe tests and asserting the server returns a
Parse.Error.INVALID_QUERY (HTTP 400) for each payload; reference the existing
test patterns that use Parse.Query and query.subscribe() and replicate them by
constructing the equivalent {"where": { $or: { "0": {...}, length: 1 } }} (and
similar for $and/$nor and the non-protected-field $or) in the REST request body
so the REST query path is validated the same as the LiveQuery path.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 1a3badc6-d95e-4060-8e34-95f2982e277b
📒 Files selected for processing (4)
spec/vulnerabilities.spec.jssrc/LiveQuery/ParseLiveQueryServer.tssrc/LiveQuery/QueryTools.jssrc/RestQuery.js
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## alpha #10350 +/- ##
==========================================
- Coverage 92.53% 92.52% -0.02%
==========================================
Files 192 192
Lines 16541 16552 +11
Branches 229 231 +2
==========================================
+ Hits 15306 15314 +8
- Misses 1215 1216 +1
- Partials 20 22 +2 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
|
@coderabbitai review |
✅ Actions performedReview triggered.
|
|
@coderabbitai review |
✅ Actions performedReview triggered.
|
# [9.7.0-alpha.16](9.7.0-alpha.15...9.7.0-alpha.16) (2026-03-29) ### Bug Fixes * LiveQuery protected-field guard bypass via array-like logical operator value ([GHSA-mmg8-87c5-jrc2](https://github.com/parse-community/parse-server/security/advisories/GHSA-mmg8-87c5-jrc2)) ([#10350](#10350)) ([f63fd1a](f63fd1a))
|
🎉 This change has been released in version 9.7.0-alpha.16 |
# [9.7.0](9.6.1...9.7.0) (2026-03-30) ### Bug Fixes * Auth data exposed via verify password endpoint ([GHSA-wp76-gg32-8258](GHSA-wp76-gg32-8258)) ([#10323](#10323)) ([770be86](770be86)) * Batch login sub-request rate limit uses IP-based keying ([#10349](#10349)) ([63c37c4](63c37c4)) * Cloud Code trigger context vulnerable to prototype pollution ([#10352](#10352)) ([d5f5128](d5f5128)) * Cloud function validator bypass via prototype chain traversal ([GHSA-vpj2-qq7w-5qq6](GHSA-vpj2-qq7w-5qq6)) ([#10342](#10342)) ([dc59e27](dc59e27)) * Duplicate session destruction can cause unhandled promise rejection ([#10319](#10319)) ([92791c1](92791c1)) * GraphQL API endpoint ignores CORS origin restriction ([GHSA-q3p6-g7c4-829c](GHSA-q3p6-g7c4-829c)) ([#10334](#10334)) ([4dd0d3d](4dd0d3d)) * GraphQL complexity validator exponential fragment traversal DoS ([GHSA-mfj6-6p54-m98c](GHSA-mfj6-6p54-m98c)) ([#10344](#10344)) ([f759bda](f759bda)) * LiveQuery protected field leak via shared mutable state across concurrent subscribers ([GHSA-m983-v2ff-wq65](GHSA-m983-v2ff-wq65)) ([#10330](#10330)) ([776c71c](776c71c)) * LiveQuery protected-field guard bypass via array-like logical operator value ([GHSA-mmg8-87c5-jrc2](GHSA-mmg8-87c5-jrc2)) ([#10350](#10350)) ([f63fd1a](f63fd1a)) * Maintenance key blocked from querying protected fields ([#10290](#10290)) ([7c8b213](7c8b213)) * MFA single-use token bypass via concurrent authData login requests ([GHSA-w73w-g5xw-rwhf](GHSA-w73w-g5xw-rwhf)) ([#10326](#10326)) ([e7efbeb](e7efbeb)) * Missing error messages in Parse errors ([#10304](#10304)) ([f128048](f128048)) * Postgres query on non-existent column throws internal server error ([#10308](#10308)) ([c5c4325](c5c4325)) * Session field immutability bypass via falsy-value guard ([GHSA-f6j3-w9v3-cq22](GHSA-f6j3-w9v3-cq22)) ([#10347](#10347)) ([9080296](9080296)) ### Features * Add `protectedFieldsSaveResponseExempt` option to strip protected fields from save responses ([#10289](#10289)) ([4f7cb53](4f7cb53)) * Add `protectedFieldsTriggerExempt` option to exempt Cloud Code triggers from `protectedFields` ([#10288](#10288)) ([1610f98](1610f98)) * Add support for `partialFilterExpression` in MongoDB storage adapter ([#10346](#10346)) ([8dd7bf2](8dd7bf2)) * Extend storage adapter interface to optionally return `matchedCount` and `modifiedCount` from `DatabaseController.update` with `many: true` ([#10353](#10353)) ([aea7596](aea7596))
|
🎉 This change has been released in version 9.7.0 |
Issue
LiveQuery protected-field guard bypass via array-like logical operator value (GHSA-mmg8-87c5-jrc2)