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