CVE-2014-125048: Session Fixation (CWE-384)
value: A vulnerability, which was classified as critical, has been found in kassi xingwall. This issue affects some unknown processing of the file app/controllers/oauth.js. The manipulation leads to session fixiation. The patch is named e9f0d509e1408743048e29d9c099d36e0e1f6ae7. It is recommended to apply a patch to fix this issue. The associated identifier of this vulnerability is VDB-217559.
CWE description: Authenticating a user, or otherwise establishing a new user session, without invalidating any existing session identifier gives an attacker the opportunity to steal authenticated sessions.
CVSS v3 base score: 5.4
Published: 2023-01-06T13:15Z
Repository: https://github.com/kassi/xingwall
Language: JavaScript
Files changed: app/controllers/oauth.js
Commit date: 2014-11-20 11:32:57 +0100
Commit message: Regenerate session after XING login to fix "session fixation" vulnerability

Diff: diff --git a/app/controllers/oauth.js b/app/controllers/oauth.js
index 1835101..44d755e 100644
--- a/app/controllers/oauth.js
+++ b/app/controllers/oauth.js
@@ -33,55 +33,61 @@ module.exports = function (app, io) {
 
     var requestToken = JSON.parse(req.signedCookies.requestToken);
 
     xingApi.getAccessToken(requestToken.token, requestToken.secret, req.query.oauth_verifier,
       function (error, oauthToken, oauthTokenSecret) {
-        res.cookie('requestToken', null); // delete cookie
-
-        var client = xingApi.client(oauthToken, oauthTokenSecret);
-
-        client.get('/v1/users/me', function (error, response) {
-          var user = JSON.parse(response).users[0];
-
-          Wall.findOne({ _id: req.query.wall_id }).exec()
-            .then(function (wall) {
-
-              var profile = new Profile({
-                userId: user.id,
-                displayName: user.display_name,
-                photoUrls: {
-                  size_128x128: user.photo_urls.size_128x128,
-                  size_256x256: user.photo_urls.size_256x256
-                }
-              }).toObject();
-
-              delete profile._id; // make sure that we don't overwrite the internal _id on an update
-
-              Profile.findOneAndUpdate({ userId: user.id }, profile, { upsert: true }).exec()
-                .then(function (profile) {
-                  wall.profiles.pull(profile._id);
-                  wall.profiles.push(profile._id);
-
-                  wall.save(function (err) {
-                    if (err) {
-                      console.error(err);
-                      res.render('error');
-                    } else {
-                      req.session.user = {
-                        id: profile._id,
-                        oauthToken: oauthToken,
-                        oauthTokenSecret: oauthTokenSecret
-                      };
-
-                      io.emit('profiles:updated');
-                      res.render('oauth/callback', { url: "/walls/" + req.query.wall_id });
-                    }
+        if (error) {
+          console.log(error);
+          res.render('error');
+          return;
+        }
+        req.session.regenerate(function (err) {
+          res.cookie('requestToken', null); // delete cookie
+
+          var client = xingApi.client(oauthToken, oauthTokenSecret);
+
+          client.get('/v1/users/me', function (error, response) {
+            var user = JSON.parse(response).users[0];
+
+            Wall.findOne({ _id: req.query.wall_id }).exec()
+              .then(function (wall) {
+
+                var profile = new Profile({
+                  userId: user.id,
+                  displayName: user.display_name,
+                  photoUrls: {
+                    size_128x128: user.photo_urls.size_128x128,
+                    size_256x256: user.photo_urls.size_256x256
+                  }
+                }).toObject();
+
+                delete profile._id; // make sure that we don't overwrite the internal _id on an update
+
+                Profile.findOneAndUpdate({ userId: user.id }, profile, { upsert: true }).exec()
+                  .then(function (profile) {
+                    wall.profiles.pull(profile._id);
+                    wall.profiles.push(profile._id);
+
+                    wall.save(function (err) {
+                      if (err) {
+                        console.error(err);
+                        res.render('error');
+                      } else {
+                        req.session.user = {
+                          id: profile._id,
+                          oauthToken: oauthToken,
+                          oauthTokenSecret: oauthTokenSecret
+                        };
+
+                        io.emit('profiles:updated');
+                        res.render('oauth/callback', { url: "/walls/" + req.query.wall_id });
+                      }
+                    });
                   });
-                });
-
-            }, function (err) {
-              console.log(err);
-            });
+              }, function (err) {
+                console.log(err);
+              });
+          });
         });
       });
   });
 };

Vulnerable code:         res.cookie('requestToken', null); // delete cookie

        var client = xingApi.client(oauthToken, oauthTokenSecret);

        client.get('/v1/users/me', function (error, response) {
          var user = JSON.parse(response).users[0];

          Wall.findOne({ _id: req.query.wall_id }).exec()
            .then(function (wall) {

              var profile = new Profile({
                userId: user.id,
                displayName: user.display_name,
                photoUrls: {
                  size_128x128: user.photo_urls.size_128x128,
                  size_256x256: user.photo_urls.size_256x256
                }
              }).toObject();

              delete profile._id; // make sure that we don't overwrite the internal _id on an update

              Profile.findOneAndUpdate({ userId: user.id }, profile, { upsert: true }).exec()
                .then(function (profile) {
                  wall.profiles.pull(profile._id);
                  wall.profiles.push(profile._id);

                  wall.save(function (err) {
                    if (err) {
                      console.error(err);
                      res.render('error');
                    } else {
                      req.session.user = {
                        id: profile._id,
                        oauthToken: oauthToken,
                        oauthTokenSecret: oauthTokenSecret
                      };

                      io.emit('profiles:updated');
                      res.render('oauth/callback', { url: "/walls/" + req.query.wall_id });
                    }
                });

            }, function (err) {
              console.log(err);
            });
Fixed code:         if (error) {
          console.log(error);
          res.render('error');
          return;
        }
        req.session.regenerate(function (err) {
          res.cookie('requestToken', null); // delete cookie

          var client = xingApi.client(oauthToken, oauthTokenSecret);

          client.get('/v1/users/me', function (error, response) {
            var user = JSON.parse(response).users[0];

            Wall.findOne({ _id: req.query.wall_id }).exec()
              .then(function (wall) {

                var profile = new Profile({
                  userId: user.id,
                  displayName: user.display_name,
                  photoUrls: {
                    size_128x128: user.photo_urls.size_128x128,
                    size_256x256: user.photo_urls.size_256x256
                  }
                }).toObject();

                delete profile._id; // make sure that we don't overwrite the internal _id on an update

                Profile.findOneAndUpdate({ userId: user.id }, profile, { upsert: true }).exec()
                  .then(function (profile) {
                    wall.profiles.pull(profile._id);
                    wall.profiles.push(profile._id);

                    wall.save(function (err) {
                      if (err) {
                        console.error(err);
                        res.render('error');
                      } else {
                        req.session.user = {
                          id: profile._id,
                          oauthToken: oauthToken,
                          oauthTokenSecret: oauthTokenSecret
                        };

                        io.emit('profiles:updated');
                        res.render('oauth/callback', { url: "/walls/" + req.query.wall_id });
                      }
                    });
              }, function (err) {
                console.log(err);
              });
          });