Well, I understand the concerns with trying to patch all libs that PHP uses. However mysql seems to be a *major* extension, as in it is very heavily used. I had to write this patch anyway for a client, so I will post the patch here. If people don't like it, they can ignore it. If enough people do like it, we can discuss committing it.
This patch I think will catch all cases, unless there is some way that mysql can escape characters (\x44 or something). -James The University of Vermont On Mon, 4 Feb 2002, Rasmus Lerdorf wrote: > The fact that 3rd party libs can load arbitrary files is not a new > concept. Every time I give a moderately detailed PHP talk I mention the > fact that there is a way to load a file through the oci8 libs. Of course > it can be done through the mysql libs as well. This is not a new concept. > All someone woulod have had to do to learn of this "vulnerability" would > have been to go to any of the PHP talks I have given in the past 3 years. > > We will not scan queries to catch these. Safe mode is a crappy fix to a > problem that isn't ours. > > -Rasmus > > > On Tue, 5 Feb 2002, Andi Gutmans wrote: > > > We have always said that safe mode isn't very safe. I'm sure there are > > other ways of circumventing it. > > Unless a few people focus specifically on safe mode I don't think this will > > change. > > > > Andi > > > > At 12:26 AM 2/5/2002 -0500, James E. Flemer wrote: > > >BTW I just noticed that this has been entered as bug > > >#15375. > > > > > > > > >-- > > >PHP Development Mailing List <http://www.php.net/> > > >To unsubscribe, visit: http://www.php.net/unsub.php > > > > > > > > > >
Index: ext/mysql/php_mysql.c =================================================================== RCS file: /repository/php4/ext/mysql/php_mysql.c,v retrieving revision 1.115 diff -u -r1.115 php_mysql.c --- ext/mysql/php_mysql.c 30 Dec 2001 10:00:26 -0000 1.115 +++ ext/mysql/php_mysql.c 5 Feb 2002 21:25:30 -0000 @@ -987,6 +987,66 @@ /* }}} */ #endif +/* {{{ php_mysql_safety_check + */ +static int php_mysql_safety_check(const char *p, int len) +{ + int state = 1; + const char *end = p + len; + + while (p && *p && p < end) + { + switch (state) + { + case 0: /* skip word */ + while (*p && p < end && *p != ' ' && *p != '\t' && *p != '\r' +&& *p != '\n') + p++; + /* FALLTHROUGH */ + case 2: + /* FALLTHROUGH */ + case 4: /* move to the end of space(s) */ + if (*p && p < end && *p != ' ' && *p != '\t' && *p != '\r' && +*p != '\n') { + state = 0; + break; + } + while (*p && p < end && (*p == ' ' || *p == '\t' || *p == '\r' +|| *p == '\n')) + p++; + state++; + break; + case 1: /* look for "LOAD" */ + if ( (*p == 'l' || *p == 'L') && + p+3 < end && + *(p+1) && *(p+2) && *(p+3) && + (*(p+1) == 'o' || *(p+1) == 'O') && + (*(p+2) == 'a' || *(p+2) == 'A') && + (*(p+3) == 'd' || *(p+3) == 'D') ) { + p += 4; + state++; + } else { + state = 0; + } + break; + case 3: /* look for "DATA" */ + if ( (*p == 'd' || *p == 'D') && + p+3 < end && + *(p+1) && *(p+2) && *(p+3) && + (*(p+1) == 'a' || *(p+1) == 'A') && + (*(p+2) == 't' || *(p+2) == 'T') && + (*(p+3) == 'a' || *(p+3) == 'A') ) { + p += 4; + state++; + } else { + state = 0; + } + break; + case 5: /* "<space>LOAD<space>DATA<space>" found */ + return 0; + } + } + return 1; +} +/* }}} */ + /* {{{ php_mysql_do_query_general */ static void php_mysql_do_query_general(zval **query, zval **mysql_link, int link_id, zval **db, int use_store, zval *return_value TSRMLS_DC) @@ -1021,6 +1081,15 @@ } while(0); convert_to_string_ex(query); + + /* disallow LOAD DATA if safe_mode on */ + if (PG(safe_mode)) { + if (!php_mysql_safety_check(Z_STRVAL_PP(query), Z_STRLEN_PP(query))) { + php_error(E_WARNING, "MySQL: Statement failed safe mode +checks"); + RETURN_FALSE; + } + } + /* mysql_query is binary unsafe, use mysql_real_query */ #if MYSQL_VERSION_ID > 32199 if (mysql_real_query(&mysql->conn, Z_STRVAL_PP(query), Z_STRLEN_PP(query))!=0) {
-- PHP Development Mailing List <http://www.php.net/> To unsubscribe, visit: http://www.php.net/unsub.php