Merge pull request from GHSA-7pr3-p5fm-8r9x
Some checks failed
docker / build (push) Has been cancelled
Some checks failed
docker / build (push) Has been cancelled
* fix: LQ deletes session token * add 4.10.4 * add changes
This commit is contained in:
@@ -1,5 +1,11 @@
|
|||||||
# Parse Server Changelog
|
# Parse Server Changelog
|
||||||
|
|
||||||
|
## 4.10.4
|
||||||
|
[Full Changelog](https://github.com/parse-community/parse-server/compare/4.10.3...4.10.4)
|
||||||
|
|
||||||
|
### Security Fixes
|
||||||
|
- 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)
|
||||||
|
|
||||||
# 4.10.3
|
# 4.10.3
|
||||||
|
|
||||||
## Security Fixes
|
## Security Fixes
|
||||||
|
|||||||
2
package-lock.json
generated
2
package-lock.json
generated
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "parse-server",
|
"name": "parse-server",
|
||||||
"version": "4.10.3",
|
"version": "4.10.4",
|
||||||
"lockfileVersion": 1,
|
"lockfileVersion": 1,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "parse-server",
|
"name": "parse-server",
|
||||||
"version": "4.10.3",
|
"version": "4.10.4",
|
||||||
"description": "An express module providing a Parse-compatible API server",
|
"description": "An express module providing a Parse-compatible API server",
|
||||||
"main": "lib/index.js",
|
"main": "lib/index.js",
|
||||||
"repository": {
|
"repository": {
|
||||||
|
|||||||
@@ -928,6 +928,52 @@ describe('ParseLiveQuery', function () {
|
|||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should strip out session token in LiveQuery', async () => {
|
||||||
|
await reconfigureServer({
|
||||||
|
liveQuery: { classNames: ['_User'] },
|
||||||
|
startLiveQueryServer: true,
|
||||||
|
verbose: false,
|
||||||
|
silent: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
const user = new Parse.User();
|
||||||
|
user.setUsername('username');
|
||||||
|
user.setPassword('password');
|
||||||
|
user.set('foo', 'bar');
|
||||||
|
|
||||||
|
const query = new Parse.Query(Parse.User);
|
||||||
|
query.equalTo('foo', 'bar');
|
||||||
|
const subscription = await query.subscribe();
|
||||||
|
|
||||||
|
const events = ['create', 'update', 'enter', 'leave', 'delete'];
|
||||||
|
const response = (obj, prev) => {
|
||||||
|
expect(obj.get('sessionToken')).toBeUndefined();
|
||||||
|
expect(obj.sessionToken).toBeUndefined();
|
||||||
|
expect(prev?.sessionToken).toBeUndefined();
|
||||||
|
if (prev && prev.get) {
|
||||||
|
expect(prev.get('sessionToken')).toBeUndefined();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const calls = {};
|
||||||
|
for (const key of events) {
|
||||||
|
calls[key] = response;
|
||||||
|
spyOn(calls, key).and.callThrough();
|
||||||
|
subscription.on(key, calls[key]);
|
||||||
|
}
|
||||||
|
await user.signUp();
|
||||||
|
user.unset('foo');
|
||||||
|
await user.save();
|
||||||
|
user.set('foo', 'bar');
|
||||||
|
await user.save();
|
||||||
|
user.set('yolo', 'bar');
|
||||||
|
await user.save();
|
||||||
|
await user.destroy();
|
||||||
|
await new Promise(resolve => process.nextTick(resolve));
|
||||||
|
for (const key of events) {
|
||||||
|
expect(calls[key]).toHaveBeenCalled();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
afterEach(async function (done) {
|
afterEach(async function (done) {
|
||||||
const client = await Parse.CoreManager.getLiveQueryController().getDefaultLiveQueryClient();
|
const client = await Parse.CoreManager.getLiveQueryController().getDefaultLiveQueryClient();
|
||||||
client.close();
|
client.close();
|
||||||
|
|||||||
@@ -3929,6 +3929,51 @@ describe('Parse.User testing', () => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should strip out authdata in LiveQuery', async () => {
|
||||||
|
const provider = getMockFacebookProvider();
|
||||||
|
Parse.User._registerAuthenticationProvider(provider);
|
||||||
|
|
||||||
|
await reconfigureServer({
|
||||||
|
liveQuery: { classNames: ['_User'] },
|
||||||
|
startLiveQueryServer: true,
|
||||||
|
verbose: false,
|
||||||
|
silent: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
const query = new Parse.Query(Parse.User);
|
||||||
|
query.doesNotExist('foo');
|
||||||
|
const subscription = await query.subscribe();
|
||||||
|
|
||||||
|
const events = ['create', 'update', 'enter', 'leave', 'delete'];
|
||||||
|
const response = (obj, prev) => {
|
||||||
|
expect(obj.get('authData')).toBeUndefined();
|
||||||
|
expect(obj.authData).toBeUndefined();
|
||||||
|
expect(prev?.authData).toBeUndefined();
|
||||||
|
if (prev && prev.get) {
|
||||||
|
expect(prev.get('authData')).toBeUndefined();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const calls = {};
|
||||||
|
for (const key of events) {
|
||||||
|
calls[key] = response;
|
||||||
|
spyOn(calls, key).and.callThrough();
|
||||||
|
subscription.on(key, calls[key]);
|
||||||
|
}
|
||||||
|
const user = await Parse.User._logInWith('facebook');
|
||||||
|
|
||||||
|
user.set('foo', 'bar');
|
||||||
|
await user.save();
|
||||||
|
user.unset('foo');
|
||||||
|
await user.save();
|
||||||
|
user.set('yolo', 'bar');
|
||||||
|
await user.save();
|
||||||
|
await user.destroy();
|
||||||
|
await new Promise(resolve => process.nextTick(resolve));
|
||||||
|
for (const key of events) {
|
||||||
|
expect(calls[key]).toHaveBeenCalled();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
describe('issue #4897', () => {
|
describe('issue #4897', () => {
|
||||||
it_only_db('mongo')('should be able to login with a legacy user (no ACL)', async () => {
|
it_only_db('mongo')('should be able to login with a legacy user (no ACL)', async () => {
|
||||||
// This issue is a side effect of the locked users and legacy users which don't have ACL's
|
// This issue is a side effect of the locked users and legacy users which don't have ACL's
|
||||||
|
|||||||
@@ -179,6 +179,14 @@ class ParseLiveQueryServer {
|
|||||||
deletedParseObject = res.object.toJSON();
|
deletedParseObject = res.object.toJSON();
|
||||||
deletedParseObject.className = className;
|
deletedParseObject.className = className;
|
||||||
}
|
}
|
||||||
|
if (
|
||||||
|
(deletedParseObject.className === '_User' ||
|
||||||
|
deletedParseObject.className === '_Session') &&
|
||||||
|
!client.hasMasterKey
|
||||||
|
) {
|
||||||
|
delete deletedParseObject.sessionToken;
|
||||||
|
delete deletedParseObject.authData;
|
||||||
|
}
|
||||||
client.pushDelete(requestId, deletedParseObject);
|
client.pushDelete(requestId, deletedParseObject);
|
||||||
})
|
})
|
||||||
.catch(error => {
|
.catch(error => {
|
||||||
@@ -315,6 +323,16 @@ class ParseLiveQueryServer {
|
|||||||
originalParseObject = res.original.toJSON();
|
originalParseObject = res.original.toJSON();
|
||||||
originalParseObject.className = res.original.className || className;
|
originalParseObject.className = res.original.className || className;
|
||||||
}
|
}
|
||||||
|
if (
|
||||||
|
(currentParseObject.className === '_User' ||
|
||||||
|
currentParseObject.className === '_Session') &&
|
||||||
|
!client.hasMasterKey
|
||||||
|
) {
|
||||||
|
delete currentParseObject.sessionToken;
|
||||||
|
delete originalParseObject?.sessionToken;
|
||||||
|
delete currentParseObject.authData;
|
||||||
|
delete originalParseObject?.authData;
|
||||||
|
}
|
||||||
const functionName =
|
const functionName =
|
||||||
'push' + message.event.charAt(0).toUpperCase() + message.event.slice(1);
|
'push' + message.event.charAt(0).toUpperCase() + message.event.slice(1);
|
||||||
if (client[functionName]) {
|
if (client[functionName]) {
|
||||||
|
|||||||
Reference in New Issue
Block a user