Skip to content

Commit 834ae36

Browse files
dblythymtrezza
andauthored
Merge pull request from GHSA-7pr3-p5fm-8r9x
* fix: strip sessionToken on _User LiveQuery * delete authData * add changelog * Update package.json * Update CHANGELOG.md * add changes * Update ParseLiveQuery.spec.js Co-authored-by: Manuel <[email protected]>
1 parent bcbc035 commit 834ae36

File tree

6 files changed

+120
-4
lines changed

6 files changed

+120
-4
lines changed

CHANGELOG.md

+9-2
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@ Jump directly to a version:
44

55
| 4.x |
66
|--------------------------------------|
7-
| [**4.10.3 (latest release)**](#4103) |
7+
| [**4.10.4 (latest release)**](#4104) |
8+
| [4.10.3](#4103) |
89
| [4.10.2](#4102) |
910
| [4.10.1](#4101) |
1011
| [4.10.0](#4100) |
@@ -94,7 +95,7 @@ Jump directly to a version:
9495
___
9596

9697
## Unreleased (Master Branch)
97-
[Full Changelog](https://github.com/parse-community/parse-server/compare/4.10.3...master)
98+
[Full Changelog](https://github.com/parse-community/parse-server/compare/4.10.4...master)
9899

99100
### Breaking Changes
100101
- Improved schema caching through database real-time hooks. Reduces DB queries, decreases Parse Query execution time and fixes a potential schema memory leak. If multiple Parse Server instances connect to the same DB (for example behind a load balancer), set the [Parse Server Option](https://parseplatform.org/parse-server/api/master/ParseServerOptions.html) `databaseOptions.enableSchemaHooks: true` to enable this feature and keep the schema in sync across all instances. Failing to do so will cause a schema change to not propagate to other instances and re-syncing will only happen when these instances restart. The options `enableSingleSchemaCache` and `schemaCacheTTL` have been removed. To use this feature with MongoDB, a replica set cluster with [change stream](https://docs.mongodb.com/manual/changeStreams/#availability) support is required. (Diamond Lewis, SebC) [#7214](https://github.com/parse-community/parse-server/issues/7214)
@@ -156,6 +157,12 @@ ___
156157
- Allow cloud string for ES modules (Daniel Blyth) [#7560](https://github.com/parse-community/parse-server/pull/7560)
157158
- docs: Introduce deprecation ID for reference in comments and online search (Manuel Trezza) [#7562](https://github.com/parse-community/parse-server/pull/7562)
158159

160+
## 4.10.4
161+
[Full Changelog](https://github.com/parse-community/parse-server/compare/4.10.3...4.10.4)
162+
163+
### Security Fixes
164+
- Strip out sessionToken when LiveQuery is used on Parse.User (Daniel Blyth) [GHSA-7pr3-p5fm-8r9x](https://github.com/parse-community/parse-server/security/advisories/GHSA-7pr3-p5fm-8r9x)
165+
159166
## 4.10.3
160167
[Full Changelog](https://github.com/parse-community/parse-server/compare/4.10.2...4.10.3)
161168

package-lock.json

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "parse-server",
3-
"version": "4.10.3",
3+
"version": "4.10.4",
44
"description": "An express module providing a Parse-compatible API server",
55
"main": "lib/index.js",
66
"repository": {

spec/ParseLiveQuery.spec.js

+46
Original file line numberDiff line numberDiff line change
@@ -840,6 +840,52 @@ describe('ParseLiveQuery', function () {
840840
done();
841841
});
842842

843+
it('should strip out session token in LiveQuery', async () => {
844+
await reconfigureServer({
845+
liveQuery: { classNames: ['_User'] },
846+
startLiveQueryServer: true,
847+
verbose: false,
848+
silent: true,
849+
});
850+
851+
const user = new Parse.User();
852+
user.setUsername('username');
853+
user.setPassword('password');
854+
user.set('foo', 'bar');
855+
856+
const query = new Parse.Query(Parse.User);
857+
query.equalTo('foo', 'bar');
858+
const subscription = await query.subscribe();
859+
860+
const events = ['create', 'update', 'enter', 'leave', 'delete'];
861+
const response = (obj, prev) => {
862+
expect(obj.get('sessionToken')).toBeUndefined();
863+
expect(obj.sessionToken).toBeUndefined();
864+
expect(prev?.sessionToken).toBeUndefined();
865+
if (prev && prev.get) {
866+
expect(prev.get('sessionToken')).toBeUndefined();
867+
}
868+
};
869+
const calls = {};
870+
for (const key of events) {
871+
calls[key] = response;
872+
spyOn(calls, key).and.callThrough();
873+
subscription.on(key, calls[key]);
874+
}
875+
await user.signUp();
876+
user.unset('foo');
877+
await user.save();
878+
user.set('foo', 'bar');
879+
await user.save();
880+
user.set('yolo', 'bar');
881+
await user.save();
882+
await user.destroy();
883+
await new Promise(resolve => process.nextTick(resolve));
884+
for (const key of events) {
885+
expect(calls[key]).toHaveBeenCalled();
886+
}
887+
});
888+
843889
afterEach(async function (done) {
844890
const client = await Parse.CoreManager.getLiveQueryController().getDefaultLiveQueryClient();
845891
client.close();

spec/ParseUser.spec.js

+45
Original file line numberDiff line numberDiff line change
@@ -3966,6 +3966,51 @@ describe('Parse.User testing', () => {
39663966
ok(model._isLinked('facebook'), 'User should be linked to facebook');
39673967
});
39683968
});
3969+
3970+
it('should strip out authdata in LiveQuery', async () => {
3971+
const provider = getMockFacebookProvider();
3972+
Parse.User._registerAuthenticationProvider(provider);
3973+
3974+
await reconfigureServer({
3975+
liveQuery: { classNames: ['_User'] },
3976+
startLiveQueryServer: true,
3977+
verbose: false,
3978+
silent: true,
3979+
});
3980+
3981+
const query = new Parse.Query(Parse.User);
3982+
query.doesNotExist('foo');
3983+
const subscription = await query.subscribe();
3984+
3985+
const events = ['create', 'update', 'enter', 'leave', 'delete'];
3986+
const response = (obj, prev) => {
3987+
expect(obj.get('authData')).toBeUndefined();
3988+
expect(obj.authData).toBeUndefined();
3989+
expect(prev?.authData).toBeUndefined();
3990+
if (prev && prev.get) {
3991+
expect(prev.get('authData')).toBeUndefined();
3992+
}
3993+
};
3994+
const calls = {};
3995+
for (const key of events) {
3996+
calls[key] = response;
3997+
spyOn(calls, key).and.callThrough();
3998+
subscription.on(key, calls[key]);
3999+
}
4000+
const user = await Parse.User._logInWith('facebook');
4001+
4002+
user.set('foo', 'bar');
4003+
await user.save();
4004+
user.unset('foo');
4005+
await user.save();
4006+
user.set('yolo', 'bar');
4007+
await user.save();
4008+
await user.destroy();
4009+
await new Promise(resolve => process.nextTick(resolve));
4010+
for (const key of events) {
4011+
expect(calls[key]).toHaveBeenCalled();
4012+
}
4013+
});
39694014
});
39704015

39714016
describe('Security Advisory GHSA-8w3j-g983-8jh5', function () {

src/LiveQuery/ParseLiveQueryServer.js

+18
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,14 @@ class ParseLiveQueryServer {
186186
deletedParseObject = res.object.toJSON();
187187
deletedParseObject.className = className;
188188
}
189+
if (
190+
(deletedParseObject.className === '_User' ||
191+
deletedParseObject.className === '_Session') &&
192+
!client.hasMasterKey
193+
) {
194+
delete deletedParseObject.sessionToken;
195+
delete deletedParseObject.authData;
196+
}
189197
client.pushDelete(requestId, deletedParseObject);
190198
} catch (error) {
191199
Client.pushError(
@@ -337,6 +345,16 @@ class ParseLiveQueryServer {
337345
originalParseObject = res.original.toJSON();
338346
originalParseObject.className = res.original.className || className;
339347
}
348+
if (
349+
(currentParseObject.className === '_User' ||
350+
currentParseObject.className === '_Session') &&
351+
!client.hasMasterKey
352+
) {
353+
delete currentParseObject.sessionToken;
354+
delete originalParseObject?.sessionToken;
355+
delete currentParseObject.authData;
356+
delete originalParseObject?.authData;
357+
}
340358
const functionName = 'push' + res.event.charAt(0).toUpperCase() + res.event.slice(1);
341359
if (client[functionName]) {
342360
client[functionName](requestId, currentParseObject, originalParseObject);

0 commit comments

Comments
 (0)