Skip to content

Commit 8c8ec71

Browse files
authored
fix: authentication adapter app ID validation may be circumvented; this fixes a vulnerability that affects configurations which allow users to authenticate using the Parse Server authentication adapter for *Facebook* or *Spotify* and where the server-side authentication adapter configuration appIds is set as a string (e.g. abc) instead of an array of strings (e.g. ["abc"]) ([GHSA-r657-33vp-gp22](GHSA-r657-33vp-gp22)) [skip release] (#8187)
1 parent 37fed30 commit 8c8ec71

File tree

3 files changed

+41
-16
lines changed

3 files changed

+41
-16
lines changed

spec/AuthenticationAdapters.spec.js

+23
Original file line numberDiff line numberDiff line change
@@ -419,6 +419,29 @@ describe('AuthenticationProviders', function () {
419419
expect(providerOptions).toEqual(options.facebook);
420420
});
421421

422+
it('should throw error when Facebook request appId is wrong data type', async () => {
423+
const httpsRequest = require('../lib/Adapters/Auth/httpsRequest');
424+
spyOn(httpsRequest, 'get').and.callFake(() => {
425+
return Promise.resolve({ id: 'a' });
426+
});
427+
const options = {
428+
facebook: {
429+
appIds: 'abcd',
430+
appSecret: 'secret_sauce',
431+
},
432+
};
433+
const authData = {
434+
access_token: 'badtoken',
435+
};
436+
const { adapter, appIds, providerOptions } = authenticationLoader.loadAuthAdapter(
437+
'facebook',
438+
options
439+
);
440+
await expectAsync(adapter.validateAppId(appIds, authData, providerOptions)).toBeRejectedWith(
441+
new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'appIds must be an array.')
442+
);
443+
});
444+
422445
it('should handle Facebook appSecret for validating appIds', async () => {
423446
const httpsRequest = require('../lib/Adapters/Auth/httpsRequest');
424447
spyOn(httpsRequest, 'get').and.callFake(() => {

src/Adapters/Auth/facebook.js

+10-9
Original file line numberDiff line numberDiff line change
@@ -32,22 +32,23 @@ function validateGraphToken(authData, options) {
3232
});
3333
}
3434

35-
function validateGraphAppId(appIds, authData, options) {
35+
async function validateGraphAppId(appIds, authData, options) {
3636
var access_token = authData.access_token;
3737
if (process.env.TESTING && access_token === 'test') {
38-
return Promise.resolve();
38+
return;
39+
}
40+
if (!Array.isArray(appIds)) {
41+
throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'appIds must be an array.');
3942
}
4043
if (!appIds.length) {
4144
throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Facebook auth is not configured.');
4245
}
43-
return graphRequest(
44-
'app?access_token=' + access_token + getAppSecretPath(authData, options)
45-
).then(data => {
46-
if (data && appIds.indexOf(data.id) != -1) {
47-
return;
48-
}
46+
const data = await graphRequest(
47+
`app?access_token=${access_token}${getAppSecretPath(authData, options)}`
48+
);
49+
if (!data || !appIds.includes(data.id)) {
4950
throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Facebook auth is invalid for this user.');
50-
});
51+
}
5152
}
5253

5354
const getFacebookKeyByKeyId = async (keyId, cacheMaxEntries, cacheMaxAge) => {

src/Adapters/Auth/spotify.js

+8-7
Original file line numberDiff line numberDiff line change
@@ -13,17 +13,18 @@ function validateAuthData(authData) {
1313
}
1414

1515
// Returns a promise that fulfills if this app id is valid.
16-
function validateAppId(appIds, authData) {
17-
var access_token = authData.access_token;
16+
async function validateAppId(appIds, authData) {
17+
const access_token = authData.access_token;
18+
if (!Array.isArray(appIds)) {
19+
throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'appIds must be an array.');
20+
}
1821
if (!appIds.length) {
1922
throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Spotify auth is not configured.');
2023
}
21-
return request('me', access_token).then(data => {
22-
if (data && appIds.indexOf(data.id) != -1) {
23-
return;
24-
}
24+
const data = await request('me', access_token);
25+
if (!data || !appIds.includes(data.id)) {
2526
throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Spotify auth is invalid for this user.');
26-
});
27+
}
2728
}
2829

2930
// A promisey wrapper for Spotify API requests.

0 commit comments

Comments
 (0)