diff --git a/ChangeLog b/ChangeLog index 7d6928ba..1b77b4c6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -4,6 +4,8 @@ Anything we add/remove/fix/change is in here (even our rants) Fish (F), Mark (M), DeadNotBuried (D) =============================================================================== * NeoStats * Version 3.0.a3-dev + - Fix a potential security vulnerbility with user supplied strings (F) + - NeoStats now compiles and runs on Mac OSX (Tiger) (F) - Introduce module override to allow a module bot to become the primary source of signon CTCP version requests. (M) - Add broadcast forms of CTCP events so that modules can watch just their own diff --git a/include/neostats.h b/include/neostats.h index ca13dc4f..09aec685 100644 --- a/include/neostats.h +++ b/include/neostats.h @@ -1221,6 +1221,7 @@ EXPORTFUNC char *sstrdup( const char *s ); char *strlwr( char *s ); EXPORTFUNC void AddStringToList( char ***List, char S[], int *C ); EXPORTFUNC void strip_mirc_codes( char *text ); +EXPORTFUNC void clean_string(char *text, size_t len); EXPORTFUNC char *sctime( time_t t ); EXPORTFUNC char *sftime( time_t t ); EXPORTFUNC char *make_safe_filename( char *name ); diff --git a/modules/connectserv/cs.c b/modules/connectserv/cs.c index f3168862..d17cb74f 100644 --- a/modules/connectserv/cs.c +++ b/modules/connectserv/cs.c @@ -289,6 +289,10 @@ static void cs_report( const char *fmt, ... ) va_start( ap, fmt ); ircvsnprintf( buf, BUFSIZE, fmt, ap ); va_end( ap ); + + /* make sure the user can't use format specifers to crash/buffer overflow */ + clean_string(buf, BUFSIZE); + irc_chanalert( cs_bot, buf ); if( cs_cfg.logging ) nlog( LOG_NORMAL, buf ); diff --git a/src/misc.c b/src/misc.c index 98fa07d6..d266833f 100644 --- a/src/misc.c +++ b/src/misc.c @@ -363,6 +363,44 @@ void strip_mirc_codes( char *text ) *dd = 0; } +/** @brief clean_string + * + * cleans up a string, escaping some vars that could be used to + * crash neostats (like format strings, %s %d etc) + * + * @param text to clean + * + * @returns none + */ + +void clean_string( char *text, size_t len ) +{ + char *dd, *start, *orig; + int i = 0; + dd = malloc(len); + start = dd; + orig = text; + + while( *text ) { + i++; + switch( *text ) { + case '%': + /* if our final length is bigger than the buffer, then we just + * drop the char */ + if ( (i+1) <= len) { + *dd++ = '%'; + } else { + *text++; + } + break; + } + *dd++ = *text++; /* Move on to the next char */ + } + *dd = 0; + strncpy(orig,start,len); + free(start); +} + /** @brief sctime * *