Skip to content

feat: Add protectedFieldsOwnerExempt option to control _User class owner exemption for protectedFields#10280

Merged
mtrezza merged 4 commits intoparse-community:alphafrom
mtrezza:feat/protected-fields-owner-exempt
Mar 22, 2026
Merged

feat: Add protectedFieldsOwnerExempt option to control _User class owner exemption for protectedFields#10280
mtrezza merged 4 commits intoparse-community:alphafrom
mtrezza:feat/protected-fields-owner-exempt

Conversation

@mtrezza
Copy link
Member

@mtrezza mtrezza commented Mar 22, 2026

Issue

The _User class has a special exemption in filterSensitiveData that skips protectedFields filtering when the logged-in user queries their own user object. This exemption does not exist for any other class, creating inconsistent behavior. This adds a new protectedFieldsOwnerExempt option (default: true) to control this exemption, with a deprecation warning that the default will change to false in a future major version.

Tasks

  • New Parse Server Tests

Summary by CodeRabbit

  • New Features

    • Added protectedFieldsOwnerExempt option to control whether users can see protected fields on their own _User records (default: true).
  • Tests

    • Added tests covering owner-exempt vs non-exempt behavior, cross-class cases, and current-user endpoints.
  • Documentation

    • Updated docs to describe per-class/per-group protectedFields configuration, selector semantics, defaults, and the new owner-exempt setting.
  • Chores

    • Added a deprecation notice for an upcoming default change to the owner-exempt behavior.

@parse-github-assistant
Copy link

parse-github-assistant bot commented Mar 22, 2026

🚀 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

  • Keep pull requests small. Large PRs will be rejected. Break complex features into smaller, incremental PRs.
  • Use Test Driven Development. Write failing tests before implementing functionality. Ensure tests pass.
  • Group code into logical blocks. Add a short comment before each block to explain its purpose.
  • We offer conceptual guidance. Coding is up to you. PRs must be merge-ready for human review.
  • Our review focuses on concept, not quality. PRs with code issues will be rejected. Use an AI agent.
  • Human review time is precious. Avoid review ping-pong. Inspect and test your AI-generated code.

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.

@parseplatformorg
Copy link
Contributor

parseplatformorg commented Mar 22, 2026

Snyk checks have passed. No issues have been found so far.

Status Scan Engine Critical High Medium Low Total (0)
Open Source Security 0 0 0 0 0 issues

💻 Catch issues earlier using the plugins for VS Code, JetBrains IDEs, Visual Studio, and Eclipse.

@coderabbitai
Copy link

coderabbitai bot commented Mar 22, 2026

📝 Walkthrough

Walkthrough

Adds a new boolean option protectedFieldsOwnerExempt (default true) and makes _User owner exemption from protectedFields conditional on that option; updates DatabaseController and LiveQuery call sites, expands options/docs, adds a deprecation entry, and adds tests covering owner vs non-owner visibility and /users/me behavior.

Changes

Cohort / File(s) Summary
Tests
spec/ProtectedFields.spec.js
New test suite validating protectedFieldsOwnerExempt for _User (owner vs other user, master key) and verifying non-_User classes and GET /1/users/me behavior.
Core Logic
src/Controllers/DatabaseController.js, src/LiveQuery/ParseLiveQueryServer.ts
DatabaseController.filterSensitiveData gains an optional protectedFieldsOwnerExempt parameter; _User owner-exemption and addProtectedFields checks are conditional on this option. LiveQuery now passes the option into the filter call.
Options / Docs
src/Options/Definitions.js, src/Options/docs.js, src/Options/index.js
Adds protectedFieldsOwnerExempt option (PARSE_SERVER_PROTECTED_FIELDS_OWNER_EXEMPT, default true) and expands protectedFields docstring to describe per-class/per-group configuration, intersection rules, and owner-exemption semantics.
Deprecation
src/Deprecator/Deprecations.js
Adds deprecation entry declaring a future default change for protectedFieldsOwnerExempt to false with guidance for migration.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~35 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 inconclusive)

Check name Status Explanation Resolution
Description check ❓ Inconclusive The description is incomplete and missing required sections from the template. It addresses Issue and includes an incomplete Tasks section, but lacks documentation and security check items fully documented, and the approach section could be more detailed. Complete the Tasks section with checkboxes for documentation updates and security checks; provide more detail in the Approach section about changes across multiple files.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes the primary change: adding a new protectedFieldsOwnerExempt option to control _User class owner exemption behavior for protectedFields.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@codecov
Copy link

codecov bot commented Mar 22, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 92.53%. Comparing base (875cf10) to head (360d86e).
⚠️ Report is 4 commits behind head on alpha.

Additional details and impacted files
@@           Coverage Diff           @@
##            alpha   #10280   +/-   ##
=======================================
  Coverage   92.53%   92.53%           
=======================================
  Files         192      192           
  Lines       16481    16482    +1     
  Branches      226      226           
=======================================
+ Hits        15251    15252    +1     
  Misses       1210     1210           
  Partials       20       20           

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (1)
spec/ProtectedFields.spec.js (1)

1861-1866: Prefer Parse.serverURL / Parse.applicationId over hardcoded test endpoint values.

Using http://localhost:8378 and 'test' directly makes these specs more brittle than necessary.

♻️ Suggested refactor pattern
+ const baseUrl = Parse.serverURL;
+ const appHeaders = {
+   'X-Parse-Application-Id': Parse.applicationId,
+   'X-Parse-REST-API-Key': 'rest',
+ };

- url: `http://localhost:8378/1/users/${user1.id}`,
+ url: `${baseUrl}/users/${user1.id}`,
  headers: {
-   'X-Parse-Application-Id': 'test',
-   'X-Parse-REST-API-Key': 'rest',
+   ...appHeaders,
    'X-Parse-Session-Token': sessionToken1,
  },

Also applies to: 1876-1881, 1902-1907, 1913-1917, 1939-1944, 1965-1970

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@spec/ProtectedFields.spec.js` around lines 1861 - 1866, Replace hardcoded
endpoint and app id in the test request construction with the Parse SDK config:
build the request URL using Parse.serverURL instead of "http://localhost:8378"
and set the 'X-Parse-Application-Id' header to Parse.applicationId instead of
the literal 'test'; update every occurrence shown (the request block that uses
url: `http://localhost:8378/1/users/${user1.id}` and headers with 'test') as
well as the other occurrences mentioned (around the blocks using sessionToken1
and user1.id) so tests reference Parse.serverURL and Parse.applicationId,
leaving sessionToken1 and user1.id unchanged.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/Controllers/DatabaseController.js`:
- Line 1673: The fast-path that returns null when a caller's id matches
query.objectId should be limited to _User class queries: update the condition in
DatabaseController (the if using this.options.protectedFieldsOwnerExempt,
aclGroup, and query.objectId) to also require the query's class is "_User"
(e.g., check query.className or the appropriate class identifier used in this
code) so non-_User classes with the same objectId do not bypass protectedFields;
leave the existing protectedFieldsOwnerExempt flag and aclGroup logic intact.

In `@src/Options/docs.js`:
- Around line 91-92: Update the docs to list the full selector set accepted by
protectedFields (including per-user entries keyed by user objectId and
selectors: '*', 'authenticated', 'role:RoleName', 'userField:FieldName') and add
a migration note describing the default behavior and planned flip for
protectedFieldsOwnerExempt (current default true and planned change), and ensure
addProtectedFields() behavior is mentioned; make the change by updating the
source option in Options.index (the canonical definition for protectedFields and
protectedFieldsOwnerExempt) and then regenerate Definitions and docs via the
definitions build step (npm run definitions) so src/Options/Definitions.js and
src/Options/docs.js reflect the complete selector set and migration path.

---

Nitpick comments:
In `@spec/ProtectedFields.spec.js`:
- Around line 1861-1866: Replace hardcoded endpoint and app id in the test
request construction with the Parse SDK config: build the request URL using
Parse.serverURL instead of "http://localhost:8378" and set the
'X-Parse-Application-Id' header to Parse.applicationId instead of the literal
'test'; update every occurrence shown (the request block that uses url:
`http://localhost:8378/1/users/${user1.id}` and headers with 'test') as well as
the other occurrences mentioned (around the blocks using sessionToken1 and
user1.id) so tests reference Parse.serverURL and Parse.applicationId, leaving
sessionToken1 and user1.id unchanged.
🪄 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: 0914b3e0-3d09-4b6d-ad96-02e4ddf1b61a

📥 Commits

Reviewing files that changed from the base of the PR and between 564c845 and 8e90dfa.

📒 Files selected for processing (6)
  • spec/ProtectedFields.spec.js
  • src/Controllers/DatabaseController.js
  • src/Deprecator/Deprecations.js
  • src/Options/Definitions.js
  • src/Options/docs.js
  • src/Options/index.js

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/Controllers/DatabaseController.js`:
- Around line 198-199: The call in ParseLiveQueryServer that invokes
DatabaseController.filterSensitiveData mistakenly passes query as the 10th
argument instead of the protectedFieldsOwnerExempt flag, causing
protectedFieldsOwnerExempt to be undefined; update the
ParseLiveQueryServer.filterSensitiveData invocation to pass
this.options.protectedFieldsOwnerExempt (or the local protectedFieldsOwnerExempt
variable) as the 10th parameter so the DatabaseController.filterSensitiveData
call receives the same protectedFieldsOwnerExempt value propagated by
DatabaseController.js and respects a false setting.
🪄 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: ee2c2e4b-7d73-4c68-a909-94295ae4a832

📥 Commits

Reviewing files that changed from the base of the PR and between 8e90dfa and 41d6a17.

📒 Files selected for processing (1)
  • src/Controllers/DatabaseController.js

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/Options/index.js`:
- Around line 171-177: Update the help text for the option
protectedFieldsOwnerExempt in src/Options/index.js to include a deprecation
notice that the default will change from true to false in a future major release
(mention which future major version if known), then run npm run definitions so
the change is propagated into the generated Definitions and docs (References:
protectedFieldsOwnerExempt, protectedFields); ensure the new deprecation
sentence is appended to the existing help paragraph and preserves the ENV and
DEFAULT annotations so definitions generation succeeds.
🪄 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: 16e05a55-ade4-4e5e-a426-e9222155cec7

📥 Commits

Reviewing files that changed from the base of the PR and between 41d6a17 and 360d86e.

📒 Files selected for processing (4)
  • src/LiveQuery/ParseLiveQueryServer.ts
  • src/Options/Definitions.js
  • src/Options/docs.js
  • src/Options/index.js
🚧 Files skipped from review as they are similar to previous changes (2)
  • src/Options/docs.js
  • src/Options/Definitions.js

@mtrezza mtrezza merged commit d5213f8 into parse-community:alpha Mar 22, 2026
23 of 24 checks passed
parseplatformorg pushed a commit that referenced this pull request Mar 22, 2026
# [9.6.0-alpha.56](9.6.0-alpha.55...9.6.0-alpha.56) (2026-03-22)

### Features

* Add `protectedFieldsOwnerExempt` option to control `_User` class owner exemption for `protectedFields` ([#10280](#10280)) ([d5213f8](d5213f8))
@parseplatformorg
Copy link
Contributor

🎉 This change has been released in version 9.6.0-alpha.56

@parseplatformorg parseplatformorg added the state:released-alpha Released as alpha version label Mar 22, 2026
@mtrezza mtrezza deleted the feat/protected-fields-owner-exempt branch March 22, 2026 16:57
parseplatformorg pushed a commit that referenced this pull request Mar 22, 2026
# [9.6.0](9.5.1...9.6.0) (2026-03-22)

### Bug Fixes

*  LiveQuery `regexTimeout` default value not applied ([#10156](#10156)) ([416cfbc](416cfbc))
* Account lockout race condition allows bypassing threshold via concurrent requests ([#10266](#10266)) ([ff70fee](ff70fee))
* Account takeover via operator injection in authentication data identifier ([GHSA-5fw2-8jcv-xh87](GHSA-5fw2-8jcv-xh87)) ([#10185](#10185)) ([0d0a554](0d0a554))
* Add configurable batch request sub-request limit via option `requestComplexity.batchRequestLimit` ([#10265](#10265)) ([164ed0d](164ed0d))
* Auth data exposed via /users/me endpoint ([GHSA-37mj-c2wf-cx96](GHSA-37mj-c2wf-cx96)) ([#10278](#10278)) ([875cf10](875cf10))
* Auth provider validation bypass on login via partial authData ([GHSA-pfj7-wv7c-22pr](GHSA-pfj7-wv7c-22pr)) ([#10246](#10246)) ([98f4ba5](98f4ba5))
* Block dot-notation updates to authData sub-fields and harden login provider checks ([#10223](#10223)) ([12c24c6](12c24c6))
* Bypass of class-level permissions in LiveQuery ([GHSA-7ch5-98q2-7289](GHSA-7ch5-98q2-7289)) ([#10133](#10133)) ([98188d9](98188d9))
* Classes `_GraphQLConfig` and `_Audience` master key bypass via generic class routes ([GHSA-7xg7-rqf6-pw6c](GHSA-7xg7-rqf6-pw6c)) ([#10151](#10151)) ([1de4e43](1de4e43))
* Cloud function dispatch crashes server via prototype chain traversal ([GHSA-4263-jgmp-7pf4](GHSA-4263-jgmp-7pf4)) ([#10210](#10210)) ([286373d](286373d))
* Concurrent signup with same authentication creates duplicate users ([#10149](#10149)) ([853bfe1](853bfe1))
* Create CLP not enforced before user field validation on signup ([#10268](#10268)) ([a0530c2](a0530c2))
* Denial of service via unindexed database query for unconfigured auth providers ([GHSA-g4cf-xj29-wqqr](GHSA-g4cf-xj29-wqqr)) ([#10270](#10270)) ([fbac847](fbac847))
* Denial-of-service via unbounded query complexity in REST and GraphQL API ([GHSA-cmj3-wx7h-ffvg](GHSA-cmj3-wx7h-ffvg)) ([#10130](#10130)) ([0ae9c25](0ae9c25))
* Email verification resend page leaks user existence (GHSA-h29g-q5c2-9h4f) ([#10238](#10238)) ([fbda4cb](fbda4cb))
* Empty authData bypasses credential requirement on signup ([GHSA-wjqw-r9x4-j59v](GHSA-wjqw-r9x4-j59v)) ([#10219](#10219)) ([5dcbf41](5dcbf41))
* GraphQL WebSocket endpoint bypasses security middleware ([GHSA-p2x3-8689-cwpg](GHSA-p2x3-8689-cwpg)) ([#10189](#10189)) ([3ffba75](3ffba75))
* Incomplete JSON key escaping in PostgreSQL Increment on nested Object fields ([#10261](#10261)) ([a692873](a692873))
* Input type validation for query operators and batch path ([#10230](#10230)) ([a628911](a628911))
* Instance comparison with `instanceof` is not realm-safe ([#10225](#10225)) ([51efb1e](51efb1e))
* LDAP injection via unsanitized user input in DN and group filter construction ([GHSA-7m6r-fhh7-r47c](GHSA-7m6r-fhh7-r47c)) ([#10154](#10154)) ([5bbca7b](5bbca7b))
* LiveQuery bypasses CLP pointer permission enforcement ([GHSA-fph2-r4qg-9576](GHSA-fph2-r4qg-9576)) ([#10250](#10250)) ([6c3317a](6c3317a))
* LiveQuery subscription query depth bypass ([GHSA-6qh5-m6g3-xhq6](GHSA-6qh5-m6g3-xhq6)) ([#10259](#10259)) ([2126fe4](2126fe4))
* LiveQuery subscription with invalid regular expression crashes server ([GHSA-827p-g5x5-h86c](GHSA-827p-g5x5-h86c)) ([#10197](#10197)) ([0ae0eee](0ae0eee))
* Locale parameter path traversal in pages router ([#10242](#10242)) ([01fb6a9](01fb6a9))
* MFA recovery code single-use bypass via concurrent requests ([GHSA-2299-ghjr-6vjp](GHSA-2299-ghjr-6vjp)) ([#10275](#10275)) ([5e70094](5e70094))
* MFA recovery codes not consumed after use ([GHSA-4hf6-3x24-c9m8](GHSA-4hf6-3x24-c9m8)) ([#10170](#10170)) ([18abdd9](18abdd9))
* Missing audience validation in Keycloak authentication adapter ([GHSA-48mh-j4p5-7j9v](GHSA-48mh-j4p5-7j9v)) ([#10137](#10137)) ([78ef1a1](78ef1a1))
* Normalize HTTP method case in `allowMethodOverride` middleware ([#10262](#10262)) ([a248e8c](a248e8c))
* NoSQL injection via token type in password reset and email verification endpoints ([GHSA-vgjh-hmwf-c588](GHSA-vgjh-hmwf-c588)) ([#10128](#10128)) ([b2f2317](b2f2317))
* OAuth2 adapter app ID validation sends wrong token to introspection endpoint ([GHSA-69xg-f649-w5g2](GHSA-69xg-f649-w5g2)) ([#10187](#10187)) ([7f9f854](7f9f854))
* OAuth2 adapter shares mutable state across providers via singleton instance ([GHSA-2cjm-2gwv-m892](GHSA-2cjm-2gwv-m892)) ([#10183](#10183)) ([6009bc1](6009bc1))
* Parse Server OAuth2 authentication adapter account takeover via identity spoofing ([GHSA-fr88-w35c-r596](GHSA-fr88-w35c-r596)) ([#10145](#10145)) ([9cfd06e](9cfd06e))
* Parse Server role escalation and CLP bypass via direct `_Join table write ([GHSA-5f92-jrq3-28rc](GHSA-5f92-jrq3-28rc)) ([#10141](#10141)) ([22faa08](22faa08))
* Parse Server session token exfiltration via `redirectClassNameForKey` query parameter ([GHSA-6r2j-cxgf-495f](GHSA-6r2j-cxgf-495f)) ([#10143](#10143)) ([70b7b07](70b7b07))
* Password reset token single-use bypass via concurrent requests ([GHSA-r3xq-68wh-gwvh](GHSA-r3xq-68wh-gwvh)) ([#10216](#10216)) ([84db0a0](84db0a0))
* Protected field change detection oracle via LiveQuery watch parameter ([GHSA-qpc3-fg4j-8hgm](GHSA-qpc3-fg4j-8hgm)) ([#10253](#10253)) ([0c0a0a5](0c0a0a5))
* Protected fields bypass via dot-notation in query and sort ([GHSA-r2m8-pxm9-9c4g](GHSA-r2m8-pxm9-9c4g)) ([#10167](#10167)) ([8f54c54](8f54c54))
* Protected fields bypass via LiveQuery subscription WHERE clause ([GHSA-j7mm-f4rv-6q6q](GHSA-j7mm-f4rv-6q6q)) ([#10175](#10175)) ([4d48847](4d48847))
* Protected fields bypass via logical query operators ([GHSA-72hp-qff8-4pvv](GHSA-72hp-qff8-4pvv)) ([#10140](#10140)) ([be1d65d](be1d65d))
* Protected fields leak via LiveQuery afterEvent trigger ([GHSA-5hmj-jcgp-6hff](GHSA-5hmj-jcgp-6hff)) ([#10232](#10232)) ([6648500](6648500))
* Query condition depth bypass via pre-validation transform pipeline ([GHSA-9fjp-q3c4-6w3j](GHSA-9fjp-q3c4-6w3j)) ([#10257](#10257)) ([85994ef](85994ef))
* Rate limit bypass via batch request endpoint ([GHSA-775h-3xrc-c228](GHSA-775h-3xrc-c228)) ([#10147](#10147)) ([2766f4f](2766f4f))
* Rate limit bypass via HTTP method override and batch method spoofing ([#10234](#10234)) ([7d72d26](7d72d26))
* Rate limit user zone key fallback and batch request bypass ([#10214](#10214)) ([434ecbe](434ecbe))
* Revert accidental breaking default values for query complexity limits ([#10205](#10205)) ([ab8dd54](ab8dd54))
* Sanitize control characters in page parameter response headers ([#10237](#10237)) ([337ffd6](337ffd6))
* Schema poisoning via prototype pollution in deep copy ([GHSA-9ccr-fpp6-78qf](GHSA-9ccr-fpp6-78qf)) ([#10200](#10200)) ([b321423](b321423))
* Security fix fast-xml-parser from 5.5.5 to 5.5.6 ([#10235](#10235)) ([f521576](f521576))
* Security upgrade fast-xml-parser from 5.3.7 to 5.4.2 ([#10086](#10086)) ([b04ca5e](b04ca5e))
* Server crash via deeply nested query condition operators ([GHSA-9xp9-j92r-p88v](GHSA-9xp9-j92r-p88v)) ([#10202](#10202)) ([f44e306](f44e306))
* Session creation endpoint allows overwriting server-generated session fields ([GHSA-5v7g-9h8f-8pgg](GHSA-5v7g-9h8f-8pgg)) ([#10195](#10195)) ([7ccfb97](7ccfb97))
* Session token expiration unchecked on cache hit ([#10194](#10194)) ([a944203](a944203))
* Session update endpoint allows overwriting server-generated session fields ([GHSA-jc39-686j-wp6q](GHSA-jc39-686j-wp6q)) ([#10263](#10263)) ([ea68fc0](ea68fc0))
* SQL injection via `Increment` operation on nested object field in PostgreSQL ([GHSA-q3vj-96h2-gwvg](GHSA-q3vj-96h2-gwvg)) ([#10161](#10161)) ([8f82282](8f82282))
* SQL injection via aggregate and distinct field names in PostgreSQL adapter ([GHSA-p2w6-rmh7-w8q3](GHSA-p2w6-rmh7-w8q3)) ([#10272](#10272)) ([bdddab5](bdddab5))
* SQL injection via dot-notation field name in PostgreSQL ([GHSA-qpr4-jrj4-6f27](GHSA-qpr4-jrj4-6f27)) ([#10159](#10159)) ([ea538a4](ea538a4))
* SQL Injection via dot-notation sub-key name in `Increment` operation on PostgreSQL ([GHSA-gqpp-xgvh-9h7h](GHSA-gqpp-xgvh-9h7h)) ([#10165](#10165)) ([169d692](169d692))
* SQL injection via query field name when using PostgreSQL ([GHSA-c442-97qw-j6c6](GHSA-c442-97qw-j6c6)) ([#10181](#10181)) ([be281b1](be281b1))
* Stored cross-site scripting (XSS) via SVG file upload ([GHSA-hcj7-6gxh-24ww](GHSA-hcj7-6gxh-24ww)) ([#10136](#10136)) ([93b784d](93b784d))
* Stored XSS filter bypass via Content-Type MIME parameter and missing XML extension blocklist entries ([GHSA-42ph-pf9q-cr72](GHSA-42ph-pf9q-cr72)) ([#10191](#10191)) ([4f53ab3](4f53ab3))
* Stored XSS via file upload of HTML-renderable file types ([GHSA-v5hf-f4c3-m5rv](GHSA-v5hf-f4c3-m5rv)) ([#10162](#10162)) ([03287cf](03287cf))
* User enumeration via email verification endpoint ([GHSA-w54v-hf9p-8856](GHSA-w54v-hf9p-8856)) ([#10172](#10172)) ([936abd4](936abd4))
* Validate authData provider values in challenge endpoint ([#10224](#10224)) ([e5e1f5b](e5e1f5b))
* Validate body field types in request middleware ([#10209](#10209)) ([df69046](df69046))
* Validate session in middleware for non-GET requests to `/sessions/me` ([#10213](#10213)) ([2a9fdab](2a9fdab))
* Validate token type in PagesRouter to prevent type confusion errors ([#10212](#10212)) ([386a989](386a989))

### Features

* Add `enableProductPurchaseLegacyApi` option to disable legacy IAP validation ([#10228](#10228)) ([622ee85](622ee85))
* Add `protectedFieldsOwnerExempt` option to control `_User` class owner exemption for `protectedFields` ([#10280](#10280)) ([d5213f8](d5213f8))
* Add `X-Content-Type-Options: nosniff` header and customizable response headers for files via `Parse.Cloud.afterFind(Parse.File)` ([#10158](#10158)) ([28d11a3](28d11a3))
@parseplatformorg
Copy link
Contributor

🎉 This change has been released in version 9.6.0

@parseplatformorg parseplatformorg added the state:released Released as stable version label Mar 22, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

state:released Released as stable version state:released-alpha Released as alpha version

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants