CVE-2022-24781 (JavaScript, published 2022-03-24T21:15Z)
Description: value: Geon is a board game based on solving questions about the Pythagorean Theorem. Malicious users can obtain the uuid from other users, spoof that uuid through the browser console and become co-owners of the target session. This issue is patched in version 1.1.0. No known workaround exists.
Severity: MEDIUM (CVSS v3 base score: 7.1)
Weakness: CWE-384 \u2014 Session Fixation
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.
Repository: https://github.com/math-geon/Geon
Files changed:
backend/src/connectionhandler.js
frontend/Geon.html
frontend/staGeon/main.js
frontend/staGeon/styles.css
Commit message: Corrigido saida de usuarios crash do backend se o client manda algo que não seja do tipo string e implementação inicial de contador de usuarios conectados

Co-Authored-By: Lobo Metalúrgico <43734867+lobometalurgico@users.noreply.github.com>


Vulnerable code:
    // ids = [];
        socket.emit('UserNameInformation', JSON.stringify({ RoomId: element.Id, UserId: element2.Id, NickName: element2.Name }));
                    <span><a href="https://github.com/emanuelfranklyn" target="_blank" >Emanuel <a target="_blank" href="https://www.talesgardem.com.br/">Franklyn</a></a>: <a target="_blank" class="EasterEgg" href="https://www.youtube.com/watch?v=KvJHqk4IgGE">Instrutor de programação do jogo.</a></span><br/>
                        <p class="PlayerInTheRoomHeader">Jogadores na sala:</p>
    CreateUsers(Data.EnteredUserId);
        playingPlayers.push({
          id: Data.UserId,
          name: Data.NickName,
        });
        element.innerHTML = Data.UserId === UserId ? `Você(${Data.NickName})` : Data.NickName;
        playingPlayers.find((object) => { return object.id === Data.oldUserId; }).id = Data.newUserId;
        playingPlayers.find((object) => { return object.id === Data.OldId; }).id = Data.NewId;
      var userName = playingPlayers.find((object) => { return object.id === element.id; }).name || 'Aguardando...';
      if (element.id === UserId) userName = `Você(${userName})`;
  Players.length -= 1;
    align: right;

Fixed code:
const timeouts = [];
          console.log('Disconnecting ' + element2.Id);
          console.log(ActiveRooms[index].Players[index2]);
          element2.socket.emit('ConnectionFailed');
          element2.socket.disconnect(0);
        console.log('Closing Room ' + element.Id);
    console.log('Active Rooms: ' + ActiveRooms.length);
    console.log('Rooms: ', ActiveRooms);
  ActiveRooms.forEach((element, index) => {
    element.Players.forEach((element2, index2) => {
      if (element2.socket === socket) {
        const timeouter = {};
        timeouter[element2.Id] = setTimeout(() => {
          console.log('Timeout ' + element2.Id);
          ids.splice(ids.indexOf(element2.Id), 1);
          timeouts.splice(timeouts.indexOf(timeouter), 1);
          cleaner();
        }, 15000);
        timeouts.push(timeouter);
        socket.broadcast.emit('Reconnecting', JSON.stringify({ RoomId: element.Id, UserId: element2.Id }));
      }
    });
  });
  if (typeof Data !== 'string') return;
  if (typeof Data !== 'string') return;

  timeouts.forEach((element, index) => {
    if (element[Data.oldUserId]) {
      console.log('User Reconnected');
      clearTimeout(element[Data.oldUserId]);
      timeouts.splice(index, 1);
    }
  });

  if (typeof Data !== 'string') {
    socket.emit('ConnectionFailed');
    socket.disconnect(0);
    socket.destroy();
    return;
  }
        socket.emit('UserNameInformation', JSON.stringify({ RoomId: element.Id, UserId: element2.Id, NickName: element2.Name }));
        console.log('Sending UserName to user: ' + element2.Id + ' ' + userName);
        element2.socket.emit('UserNameInformation', JSON.stringify({ RoomId: element.Id, UserId: Data.UserId, NickName: userName }));
                    <span><a target="_blank" href="https://github.com/emanuelfranklyn">Emanuel <a target="_blank" href="https://www.talesgardem.com.br/">Franklyn</a></a>: <a target="_blank" class="EasterEgg" href="https://www.youtube.com/watch?v=KvJHqk4IgGE">Instrutor de programação do jogo.</a></span><br/>
                    <span><a target="_blank" href="https://github.com/LoboMetalurgico">Lobo </a> <a target="_blank" href="https://beta.allonsve.com/">Metalurgico</a>: Contribuidor, progamação</span><br/>
                        <p class="PlayerInTheRoomHeader">Jogadores na sala: (0/4)</p>
    if (!document.getElementById(Data.EnteredUserId)) {
      CreateUsers(Data.EnteredUserId);
    }
    document.getElementsByClassName('PlayerInTheRoomHeader')[0].innerHTML = `Jogadores na sala: (${playingPlayers.length}/4)`;
    console.log('Received UserNameInformation: ' + Data);
    document.getElementsByClassName('PlayerInTheRoomHeader')[0].innerHTML = `Jogadores na sala: (${playingPlayers.length}/4)`;
    var userFounded = false;
    console.log(Data.UserId);
        userFounded = true;
        if (playingPlayers.find((object) => { return object.id === Data.UserId; })) {
          const player = playingPlayers.find((object) => { return object.id === Data.UserId; });
          playingPlayers[player.index].name = Data.NickName;
          console.log('Updated user on the list: ' + JSON.stringify(playingPlayers));
        } else {
          playingPlayers.push({
            id: Data.UserId,
            name: Data.NickName,
            index: playingPlayers.length,
          });
          console.log('Added new user to the list: ' + JSON.stringify(playingPlayers));
        }
        element.innerHTML = Data.UserId === UserId ? `Você (${Data.NickName})` : Data.NickName;
    if (!userFounded) {
      playingPlayers.push({
        id: Data.UserId,
        name: Data.NickName,
        index: playingPlayers.length,
      });
      console.log('Created new user to the list: ' + JSON.stringify(playingPlayers));
      console.log(Data.UserId);
      const Player = document.createElement('div');
      Player.className = 'PlayerWrapper';
      Player.id = Data.UserId;
      Player.innerHTML = Data.UserId === UserId ? `Você (${Data.NickName})` : Data.NickName;
      document.getElementsByClassName('Players')[0].appendChild(Player);
    }
    if (playingPlayers.find((object) => { return object.id === Data.UserId; })) {
      playingPlayers.splice(playingPlayers.find((object) => { return object.id === Data.UserId; }).index, 1);
    }
    document.getElementsByClassName('Players')[0].children[0].style.webkitTextStroke = '1px #FFF';
    document.getElementsByClassName('PlayerInTheRoomHeader')[0].innerHTML = `Jogadores na sala: (${playingPlayers.length}/4)`;
    document.getElementsByClassName('PlayerInTheRoomHeader')[0].innerHTML = `Jogadores na sala: (${playingPlayers.length}/4)`;
    document.getElementsByClassName('PlayerInTheRoomHeader')[0].innerHTML = `Jogadores na sala: (${playingPlayers.length}/4)`;
  socket.on('Reconnecting', (Data) => {
    Data = JSON.parse(Data);

    if (Data.RoomId !== CurrentRoom) return;

    const Players = [...document.getElementsByClassName('Players')[0].children];

    Players.forEach((element) => {
      if (element.id === Data.UserId) {
        element.innerHTML = 'Reconnecting...';
      }
    });
    document.getElementsByClassName('PlayerInTheRoomHeader')[0].innerHTML = `Jogadores na sala: (${playingPlayers.length}/4)`;
  });

        const player = playingPlayers.find((object) => { return object.id === Data.oldUserId; });
        if (player) {
          playingPlayers[player.index].id = Data.newUserId;
          console.log('changed id actual user NewId:' + Data.newUserId + ' OldId:' + Data.oldUserId + ' Index:' + player.index + ' Full Object:' + JSON.stringify(playingPlayers[player.index]));
        }
    document.getElementsByClassName('PlayerInTheRoomHeader')[0].innerHTML = `Jogadores na sala: (${playingPlayers.length}/4)`;
        const checkPlayer = playingPlayers.find((object) => { return object.id === Data.OldId; });
        if (!checkPlayer) return;
        playingPlayers[checkPlayer.index].id = Data.NewId;
        console.log('Updated some user ID: ' + Data.NewId + ' OldId:' + Data.OldId + ' Index:' + checkPlayer.index + ' Full Object:' + JSON.stringify(playingPlayers[checkPlayer.index]));
    document.getElementsByClassName('PlayerInTheRoomHeader')[0].innerHTML = `Jogadores na sala: (${playingPlayers.length}/4)`;
    document.getElementsByClassName('PlayerInTheRoomHeader')[0].innerHTML = `Jogadores na sala: (${playingPlayers.length}/4)`;
    document.getElementsByClassName('QuestionTextInput')[0].value = '';
      var userName = playingPlayers.find((object) => { return object.id === element.id; });
      console.log('UserName:' + userName.name);
      console.log('object:' + JSON.stringify(userName));
      if (!userName) { userName = 'Aguardando...'; } else { userName = userName.name; }
      console.log('UserName:' + userName.name);
      if (element.id === UserId) userName = `Você (${userName})`;
    document.getElementsByClassName('PlayerInTheRoomHeader')[0].innerHTML = `Jogadores na sala: (${playingPlayers.length}/4)`;
  document.getElementsByClassName('PlayerInTheRoomHeader')[0].innerHTML = `Jogadores na sala: (${playingPlayers.length}/4)`;
  document.getElementsByClassName('PlayerInTheRoomHeader')[0].innerHTML = `Jogadores na sala: (${playingPlayers.length}/4)`;
  document.getElementsByClassName('PlayerInTheRoomHeader')[0].innerHTML = `Jogadores na sala: (${playingPlayers.length}/4)`;