diff --git a/src/irc/core/ctcp.c b/src/irc/core/ctcp.c index 42b93411..a7b0924a 100644 --- a/src/irc/core/ctcp.c +++ b/src/irc/core/ctcp.c @@ -234,6 +234,15 @@ static void ctcp_msg(IRC_SERVER_REC *server, const char *data, if (ignore_check(SERVER(server), nick, addr, target, data, MSGLEVEL_CTCPS)) return; + /* Cap the CTCP body length that is concatenated into the signal name. + * The body comes from a remote user over IRC (PRIVMSG) and is passed + * as the second argument to any matching signal handler, including + * loaded perl scripts. A modest cap limits the attack surface for the + * dynamic-signal-name dispatch and aligns with the convention used for + * CTCP-over-DCC-chat (dcc-chat.c). */ + if (strlen(data) > 256) + return; + str = g_strconcat("ctcp msg ", data, NULL); args = strchr(str+9, ' '); if (args != NULL) *args++ = '\0'; else args = ""; @@ -254,6 +263,11 @@ static void ctcp_reply(IRC_SERVER_REC *server, const char *data, if (ignore_check(SERVER(server), nick, addr, target, data, MSGLEVEL_CTCPS)) return; + /* Cap the CTCP body length concatenated into the signal name; see + * ctcp_msg() for the rationale. */ + if (strlen(data) > 256) + return; + str = g_strconcat("ctcp reply ", data, NULL); args = strchr(str+11, ' '); if (args != NULL) *args++ = '\0'; else args = ""; diff --git a/src/irc/dcc/dcc.c b/src/irc/dcc/dcc.c index bb1c6c22..fd13165a 100644 --- a/src/irc/dcc/dcc.c +++ b/src/irc/dcc/dcc.c @@ -364,6 +364,11 @@ static void ctcp_msg_dcc(IRC_SERVER_REC *server, const char *data, if (ignore_check(SERVER(server), nick, addr, target, data, MSGLEVEL_DCC)) return; + /* Cap the CTCP body length concatenated into the signal name; see + * ctcp_msg() in ctcp.c for the rationale. */ + if (strlen(data) > 256) + return; + str = g_strconcat("ctcp msg dcc ", data, NULL); args = strchr(str+13, ' '); if (args != NULL) *args++ = '\0'; else args = ""; @@ -386,6 +391,11 @@ static void ctcp_reply_dcc(IRC_SERVER_REC *server, const char *data, if (ignore_check(SERVER(server), nick, addr, target, data, MSGLEVEL_DCC)) return; + /* Cap the CTCP body length concatenated into the signal name; see + * ctcp_msg() in ctcp.c for the rationale. */ + if (strlen(data) > 256) + return; + str = g_strconcat("ctcp reply dcc ", data, NULL); args = strchr(str+15, ' '); if (args != NULL) *args++ = '\0'; else args = "";