forked from Mirrors/openclonk
Script: Drop third AddMsgBoardCmd parameter, always escape the input
There is no reason for the engine to preprocess the input for the script. AddMsgBoardCmd doesn't enable anyone to do anything they couldn't do without it, so there's no security problem that is solved by extra input filtering, as long as all scripts use "%s" instead of plain %s.
parent
0bad4b7f59
commit
05381a63a9
|
@ -2398,24 +2398,12 @@ static bool FnSetFilmView(C4AulContext *ctx, long iToPlr)
|
|||
return true;
|
||||
}
|
||||
|
||||
static bool FnAddMsgBoardCmd(C4AulContext *ctx, C4String *pstrCommand, C4String *pstrScript, long iRestriction)
|
||||
static bool FnAddMsgBoardCmd(C4AulContext *ctx, C4String *pstrCommand, C4String *pstrScript)
|
||||
{
|
||||
// safety
|
||||
if (!pstrCommand || !pstrScript) return false;
|
||||
// unrestricted commands cannot be set by direct-exec script (like /script).
|
||||
if (iRestriction != C4MessageBoardCommand::C4MSGCMDR_Identifier)
|
||||
if (!ctx->Caller || !*ctx->Caller->Func->Name)
|
||||
return false;
|
||||
C4MessageBoardCommand::Restriction eRestriction;
|
||||
switch (iRestriction)
|
||||
{
|
||||
case C4MessageBoardCommand::C4MSGCMDR_Escaped: eRestriction = C4MessageBoardCommand::C4MSGCMDR_Escaped; break;
|
||||
case C4MessageBoardCommand::C4MSGCMDR_Plain: eRestriction = C4MessageBoardCommand::C4MSGCMDR_Plain; break;
|
||||
case C4MessageBoardCommand::C4MSGCMDR_Identifier: eRestriction = C4MessageBoardCommand::C4MSGCMDR_Identifier; break;
|
||||
default: return false;
|
||||
}
|
||||
// add command
|
||||
::MessageInput.AddCommand(FnStringPar(pstrCommand), FnStringPar(pstrScript), eRestriction);
|
||||
::MessageInput.AddCommand(FnStringPar(pstrCommand), FnStringPar(pstrScript));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -3334,10 +3322,6 @@ C4ScriptConstDef C4ScriptConstMap[]=
|
|||
{ "TEAM_AutoGenerateTeams" ,C4V_Int, C4TeamList::TEAM_AutoGenerateTeams },
|
||||
{ "TEAM_TeamColors" ,C4V_Int, C4TeamList::TEAM_TeamColors },
|
||||
|
||||
{ "C4MSGCMDR_Escaped" ,C4V_Int, C4MessageBoardCommand::C4MSGCMDR_Escaped },
|
||||
{ "C4MSGCMDR_Plain" ,C4V_Int, C4MessageBoardCommand::C4MSGCMDR_Plain },
|
||||
{ "C4MSGCMDR_Identifier" ,C4V_Int, C4MessageBoardCommand::C4MSGCMDR_Identifier },
|
||||
|
||||
{ "C4FO_Not" ,C4V_Int, C4FO_Not },
|
||||
{ "C4FO_And" ,C4V_Int, C4FO_And },
|
||||
{ "C4FO_Or" ,C4V_Int, C4FO_Or },
|
||||
|
|
|
@ -680,37 +680,12 @@ bool C4MessageInput::ProcessCommand(const char *szCommand)
|
|||
}
|
||||
else if (SSearch(CmdScript.getData(), "%s"))
|
||||
{
|
||||
// Unrestricted parameters?
|
||||
// That's kind of a security risk as it will allow anyone to execute code
|
||||
switch (pCmd->eRestriction)
|
||||
{
|
||||
case C4MessageBoardCommand::C4MSGCMDR_Escaped:
|
||||
{
|
||||
// escape strings
|
||||
StdStrBuf Par;
|
||||
Par.Copy(pCmdPar);
|
||||
Par.EscapeString();
|
||||
// compose script
|
||||
Script.Format(CmdScript.getData(), Par.getData());
|
||||
}
|
||||
break;
|
||||
|
||||
case C4MessageBoardCommand::C4MSGCMDR_Plain:
|
||||
// unescaped
|
||||
Script.Format(CmdScript.getData(), pCmdPar);
|
||||
break;
|
||||
|
||||
case C4MessageBoardCommand::C4MSGCMDR_Identifier:
|
||||
{
|
||||
// only allow identifier-characters
|
||||
StdStrBuf Par;
|
||||
while (IsIdentifier(*pCmdPar) || isspace((unsigned char)*pCmdPar))
|
||||
Par.AppendChar(*pCmdPar++);
|
||||
// compose script
|
||||
Script.Format(CmdScript.getData(), Par.getData());
|
||||
}
|
||||
break;
|
||||
}
|
||||
// escape strings
|
||||
StdStrBuf Par;
|
||||
Par.Copy(pCmdPar);
|
||||
Par.EscapeString();
|
||||
// compose script
|
||||
Script.Format(CmdScript.getData(), Par.getData());
|
||||
}
|
||||
else
|
||||
Script = CmdScript.getData();
|
||||
|
@ -726,14 +701,13 @@ bool C4MessageInput::ProcessCommand(const char *szCommand)
|
|||
return false;
|
||||
}
|
||||
|
||||
void C4MessageInput::AddCommand(const char *strCommand, const char *strScript, C4MessageBoardCommand::Restriction eRestriction)
|
||||
void C4MessageInput::AddCommand(const char *strCommand, const char *strScript)
|
||||
{
|
||||
if (GetCommand(strCommand)) return;
|
||||
// create entry
|
||||
C4MessageBoardCommand *pCmd = new C4MessageBoardCommand();
|
||||
SCopy(strCommand, pCmd->Name, C4MaxName);
|
||||
SCopy(strScript, pCmd->Script, _MAX_FNAME+30);
|
||||
pCmd->eRestriction = eRestriction;
|
||||
// add to list
|
||||
pCmd->Next = pCommands; pCommands = pCmd;
|
||||
}
|
||||
|
|
|
@ -101,8 +101,6 @@ public:
|
|||
public:
|
||||
char Name[C4MaxName + 1];
|
||||
char Script[_MAX_FNAME+30+1];
|
||||
enum Restriction { C4MSGCMDR_Escaped=0, C4MSGCMDR_Plain, C4MSGCMDR_Identifier };
|
||||
Restriction eRestriction;
|
||||
|
||||
C4MessageBoardCommand *Next;
|
||||
};
|
||||
|
@ -125,7 +123,7 @@ private:
|
|||
private:
|
||||
class C4MessageBoardCommand *pCommands;
|
||||
public:
|
||||
void AddCommand(const char *strCommand, const char *strScript, C4MessageBoardCommand::Restriction eRestriction = C4MessageBoardCommand::C4MSGCMDR_Escaped);
|
||||
void AddCommand(const char *strCommand, const char *strScript);
|
||||
class C4MessageBoardCommand *GetCommand(const char *strName);
|
||||
|
||||
// Input
|
||||
|
|
Loading…
Reference in New Issue