fix: OAuth2 adapter app ID validation sends wrong token to introspection endpoint ([GHSA-69xg-f649-w5g2](https://github.com/parse-community/parse-server/security/advisories/GHSA-69xg-f649-w5g2)) (#10188)

This commit is contained in:
Manuel
2026-03-11 23:47:44 +00:00
committed by GitHub
parent ae8d8e3b09
commit fd6f6a6ea9
2 changed files with 37 additions and 1 deletions
+36
View File
@@ -337,6 +337,42 @@ describe('OAuth2Adapter', () => {
);
});
it('should send the correct access token to the introspection endpoint during app ID validation', async () => {
const capturedTokens = [];
const originalFetch = global.fetch;
try {
global.fetch = async (url, options) => {
if (typeof url === 'string' && url === 'https://provider.com/introspect') {
const body = options?.body?.toString() || '';
const token = new URLSearchParams(body).get('token');
capturedTokens.push(token);
return {
ok: true,
json: () => Promise.resolve({
active: true,
sub: 'user123',
aud: 'valid-app-id',
}),
};
}
return originalFetch(url, options);
};
const authData = { access_token: 'myRealAccessToken', id: 'user123' };
const user = await Parse.User.logInWith('mockOauth', { authData });
expect(user.id).toBeDefined();
// With appidField configured, validateAppId and validateAuthData both call requestTokenInfo.
// Both should receive the actual access token, not 'undefined' from argument mismatch.
expect(capturedTokens.length).toBeGreaterThanOrEqual(2);
for (const token of capturedTokens) {
expect(token).toBe('myRealAccessToken');
}
} finally {
global.fetch = originalFetch;
}
});
it('should reject account takeover when useridField is omitted and attacker uses their own token with victim ID', async () => {
await reconfigureServer({
auth: {
+1 -1
View File
@@ -72,7 +72,7 @@ class OAuth2Adapter extends AuthAdapter {
this.authorizationHeader = options.authorizationHeader;
}
async validateAppId(authData) {
async validateAppId(appIds, authData) {
if (!this.appidField) {
return;
}