mirror of
https://github.com/Cockatrice/Cockatrice.git
synced 2026-09-21 09:05:10 -07:00
[Server] Fix unauthenticated crash via replay submit code (#7072)
cmdReplaySubmitCode dereferenced userInfo without an authentication guard, allowing an unauthenticated connection with a valid replay code to segfault the server. Add the same authState != PasswordRight guard used by all other replay handlers, and gate session command dispatch on a pre-auth whitelist so future handlers cannot be reached before login. Took 2 minutes Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
This commit is contained in:
parent
7971ebfe94
commit
d93f63050c
2 changed files with 52 additions and 27 deletions
|
|
@ -133,6 +133,22 @@ void Server_ProtocolHandler::sendProtocolItem(const RoomEvent &item)
|
||||||
Response::ResponseCode Server_ProtocolHandler::processSessionCommandContainer(const CommandContainer &cont,
|
Response::ResponseCode Server_ProtocolHandler::processSessionCommandContainer(const CommandContainer &cont,
|
||||||
ResponseContainer &rc)
|
ResponseContainer &rc)
|
||||||
{
|
{
|
||||||
|
const auto isPreAuthSessionCommand = [](SessionCommand::SessionCommandType type) {
|
||||||
|
switch (type) {
|
||||||
|
case SessionCommand::PING:
|
||||||
|
case SessionCommand::LOGIN:
|
||||||
|
case SessionCommand::REGISTER:
|
||||||
|
case SessionCommand::ACTIVATE:
|
||||||
|
case SessionCommand::FORGOT_PASSWORD_REQUEST:
|
||||||
|
case SessionCommand::FORGOT_PASSWORD_RESET:
|
||||||
|
case SessionCommand::FORGOT_PASSWORD_CHALLENGE:
|
||||||
|
case SessionCommand::REQUEST_PASSWORD_SALT:
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
Response::ResponseCode finalResponseCode = Response::RespOk;
|
Response::ResponseCode finalResponseCode = Response::RespOk;
|
||||||
for (int i = cont.session_command_size() - 1; i >= 0; --i) {
|
for (int i = cont.session_command_size() - 1; i >= 0; --i) {
|
||||||
Response::ResponseCode resp = Response::RespInvalidCommand;
|
Response::ResponseCode resp = Response::RespInvalidCommand;
|
||||||
|
|
@ -141,7 +157,11 @@ Response::ResponseCode Server_ProtocolHandler::processSessionCommandContainer(co
|
||||||
if (num != SessionCommand::PING) { // don't log ping commands
|
if (num != SessionCommand::PING) { // don't log ping commands
|
||||||
logDebugMessage(getSafeDebugString(sc));
|
logDebugMessage(getSafeDebugString(sc));
|
||||||
}
|
}
|
||||||
switch ((SessionCommand::SessionCommandType)num) {
|
const auto commandType = static_cast<SessionCommand::SessionCommandType>(num);
|
||||||
|
if (authState == NotLoggedIn && !isPreAuthSessionCommand(commandType)) {
|
||||||
|
resp = Response::RespLoginNeeded;
|
||||||
|
} else {
|
||||||
|
switch (commandType) {
|
||||||
case SessionCommand::PING:
|
case SessionCommand::PING:
|
||||||
resp = cmdPing(sc.GetExtension(Command_Ping::ext), rc);
|
resp = cmdPing(sc.GetExtension(Command_Ping::ext), rc);
|
||||||
break;
|
break;
|
||||||
|
|
@ -169,6 +189,7 @@ Response::ResponseCode Server_ProtocolHandler::processSessionCommandContainer(co
|
||||||
default:
|
default:
|
||||||
resp = processExtendedSessionCommand(num, sc, rc);
|
resp = processExtendedSessionCommand(num, sc, rc);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if (resp != Response::RespOk) {
|
if (resp != Response::RespOk) {
|
||||||
finalResponseCode = resp;
|
finalResponseCode = resp;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -896,6 +896,10 @@ Response::ResponseCode AbstractServerSocketInterface::cmdReplayGetCode(const Com
|
||||||
Response::ResponseCode AbstractServerSocketInterface::cmdReplaySubmitCode(const Command_ReplaySubmitCode &cmd,
|
Response::ResponseCode AbstractServerSocketInterface::cmdReplaySubmitCode(const Command_ReplaySubmitCode &cmd,
|
||||||
ResponseContainer & /*rc*/)
|
ResponseContainer & /*rc*/)
|
||||||
{
|
{
|
||||||
|
if (authState != PasswordRight) {
|
||||||
|
return Response::RespFunctionNotAllowed;
|
||||||
|
}
|
||||||
|
|
||||||
// code is of the form <game-id>-<hash>
|
// code is of the form <game-id>-<hash>
|
||||||
QString code = QString::fromStdString(cmd.replay_code());
|
QString code = QString::fromStdString(cmd.replay_code());
|
||||||
QStringList split = code.split("-");
|
QStringList split = code.split("-");
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue