VYPR
Moderate severityNVD Advisory· Published Aug 18, 2021· Updated Aug 4, 2024

New anonymous user session acts as if it's created with password

CVE-2021-39138

Description

Parse Server is an open source backend that can be deployed to any infrastructure that can run Node.js. Developers can use the REST API to signup users and also allow users to login anonymously. Prior to version 4.5.1, when an anonymous user is first signed up using REST, the server creates session incorrectly. Particularly, the authProvider field in _Session class under createdWith shows the user logged in creating a password. If a developer later depends on the createdWith field to provide a different level of access between a password user and anonymous user, the server incorrectly classified the session type as being created with a password. The server does not currently use createdWith to make decisions about internal functions, so if a developer is not using createdWith directly, they are not affected. The vulnerability only affects users who depend on createdWith by using it directly. The issue is patched in Parse Server version 4.5.1. As a workaround, do not use the createdWith Session field to make decisions if one allows anonymous login.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
parse-servernpm
< 4.5.24.5.2

Affected products

1

Patches

1
147bd9a3dc43

Merge pull request from GHSA-23r4-5mxp-c7g5

3 files changed · +65 52
  • CHANGELOG.md+6 1 modified
    @@ -1,7 +1,12 @@
     ## Parse Server Changelog
     
     ### master
    -[Full Changelog](https://github.com/parse-community/parse-server/compare/4.5.0...master)
    +[Full Changelog](https://github.com/parse-community/parse-server/compare/4.5.1...master)
    +
    +### 4.5.1
    +[Full Changelog](https://github.com/parse-community/parse-server/compare/4.5.0...4.5.1)
    +
    +- SECURITY FIX: Fixes incorrect session property `authProvider: password` of anonymous users. When signing up an anonymous user, the session field `createdWith` indicates incorrectly that the session has been created using username and password with `authProvider: password`, instead of an anonymous sign-up with `authProvider: anonymous`. This fixes the issue by setting the correct `authProvider: anonymous` for future sign-ups of anonymous users. This fix does not fix incorrect `authProvider: password` for existing sessions of anonymous users. Consider this if your app logic depends on the `authProvider` field. (Corey Baker) [GHSA-23r4-5mxp-c7g5](https://github.com/parse-community/parse-server/security/advisories/GHSA-23r4-5mxp-c7g5)
     
     ### 4.5.0
     [Full Changelog](https://github.com/parse-community/parse-server/compare/4.4.0...4.5.0)
    
  • spec/ParseUser.spec.js+55 51 modified
    @@ -2374,59 +2374,63 @@ describe('Parse.User testing', () => {
           });
       });
     
    -  it('user get session from token on signup', done => {
    -    Promise.resolve()
    -      .then(() => {
    -        return Parse.User.signUp('finn', 'human', { foo: 'bar' });
    -      })
    -      .then(user => {
    -        request({
    -          headers: {
    -            'X-Parse-Application-Id': 'test',
    -            'X-Parse-Session-Token': user.getSessionToken(),
    -            'X-Parse-REST-API-Key': 'rest',
    -          },
    -          url: 'http://localhost:8378/1/sessions/me',
    -        }).then(response => {
    -          const b = response.data;
    -          expect(typeof b.sessionToken).toEqual('string');
    -          expect(typeof b.createdWith).toEqual('object');
    -          expect(b.createdWith.action).toEqual('signup');
    -          expect(typeof b.user).toEqual('object');
    -          expect(b.user.objectId).toEqual(user.id);
    -          done();
    -        });
    -      });
    +  it('user get session from token on signup', async () => {
    +    const user = await Parse.User.signUp('finn', 'human', { foo: 'bar' });
    +    const response = await request({
    +      headers: {
    +        'X-Parse-Application-Id': 'test',
    +        'X-Parse-Session-Token': user.getSessionToken(),
    +        'X-Parse-REST-API-Key': 'rest',
    +      },
    +      url: 'http://localhost:8378/1/sessions/me',
    +    });
    +    const data = response.data;
    +    expect(typeof data.sessionToken).toEqual('string');
    +    expect(typeof data.createdWith).toEqual('object');
    +    expect(data.createdWith.action).toEqual('signup');
    +    expect(data.createdWith.authProvider).toEqual('password');
    +    expect(typeof data.user).toEqual('object');
    +    expect(data.user.objectId).toEqual(user.id);
       });
     
    -  it('user get session from token on login', done => {
    -    Promise.resolve()
    -      .then(() => {
    -        return Parse.User.signUp('finn', 'human', { foo: 'bar' });
    -      })
    -      .then(() => {
    -        return Parse.User.logOut().then(() => {
    -          return Parse.User.logIn('finn', 'human');
    -        });
    -      })
    -      .then(user => {
    -        request({
    -          headers: {
    -            'X-Parse-Application-Id': 'test',
    -            'X-Parse-Session-Token': user.getSessionToken(),
    -            'X-Parse-REST-API-Key': 'rest',
    -          },
    -          url: 'http://localhost:8378/1/sessions/me',
    -        }).then(response => {
    -          const b = response.data;
    -          expect(typeof b.sessionToken).toEqual('string');
    -          expect(typeof b.createdWith).toEqual('object');
    -          expect(b.createdWith.action).toEqual('login');
    -          expect(typeof b.user).toEqual('object');
    -          expect(b.user.objectId).toEqual(user.id);
    -          done();
    -        });
    -      });
    +  it('user get session from token on username/password login', async () => {
    +    await Parse.User.signUp('finn', 'human', { foo: 'bar' });
    +    await Parse.User.logOut();
    +    const user = await Parse.User.logIn('finn', 'human');
    +    const response = await request({
    +      headers: {
    +        'X-Parse-Application-Id': 'test',
    +        'X-Parse-Session-Token': user.getSessionToken(),
    +        'X-Parse-REST-API-Key': 'rest',
    +      },
    +      url: 'http://localhost:8378/1/sessions/me',
    +    });
    +    const data = response.data;
    +    expect(typeof data.sessionToken).toEqual('string');
    +    expect(typeof data.createdWith).toEqual('object');
    +    expect(data.createdWith.action).toEqual('login');
    +    expect(data.createdWith.authProvider).toEqual('password');
    +    expect(typeof data.user).toEqual('object');
    +    expect(data.user.objectId).toEqual(user.id);
    +  });
    +
    +  it('user get session from token on anonymous login', async () => {
    +    const user = await Parse.AnonymousUtils.logIn();
    +    const response = await request({
    +      headers: {
    +        'X-Parse-Application-Id': 'test',
    +        'X-Parse-Session-Token': user.getSessionToken(),
    +        'X-Parse-REST-API-Key': 'rest',
    +      },
    +      url: 'http://localhost:8378/1/sessions/me',
    +    });
    +    const data = response.data;
    +    expect(typeof data.sessionToken).toEqual('string');
    +    expect(typeof data.createdWith).toEqual('object');
    +    expect(data.createdWith.action).toEqual('login');
    +    expect(data.createdWith.authProvider).toEqual('anonymous');
    +    expect(typeof data.user).toEqual('object');
    +    expect(data.user.objectId).toEqual(user.id);
       });
     
       it('user update session with other field', done => {
    
  • src/RestWrite.js+4 0 modified
    @@ -857,6 +857,10 @@ RestWrite.prototype.createSessionToken = async function () {
         return;
       }
     
    +  if (this.storage['authProvider'] == null && this.data.authData) {
    +    this.storage['authProvider'] = Object.keys(this.data.authData).join(',');
    +  }
    +
       const { sessionData, createSession } = Auth.createSession(this.config, {
         userId: this.objectId(),
         createdWith: {
    

Vulnerability mechanics

Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

6

News mentions

0

No linked articles in our index yet.