Beispiel #1
0
static void suhosin_op_array_ctor(zend_op_array *op_array)
{
	TSRMLS_FETCH();

	if (suhosin_zend_extension_entry.resource_number != -1) {
	
		unsigned long suhosin_flags = 0;
		
		if (SUHOSIN_G(in_code_type) == SUHOSIN_EVAL) {
			suhosin_flags |= SUHOSIN_FLAG_CREATED_BY_EVAL;
		}
		
		op_array->reserved[suhosin_zend_extension_entry.resource_number] = (void *)suhosin_flags;
		
	}
}
Beispiel #2
0
static int suhosin_module_startup(zend_extension *extension)
{
	zend_module_entry *module_entry_ptr;
	int resid;
	TSRMLS_FETCH();
	
/*	zend_register_module(&suhosin_module_entry TSRMLS_CC); */
	
	if (zend_hash_find(&module_registry, "suhosin", sizeof("suhosin"), (void **)&module_entry_ptr)==SUCCESS) {
		
		if (extension) {
		    extension->handle = module_entry_ptr->handle;
		} else {
		    zend_extension ext;
		    ext = suhosin_zend_extension_entry;
		    ext.handle = module_entry_ptr->handle;
		    /*
		    zend_llist_add_element(&zend_extensions, &ext);
		    extension = zend_llist_get_last(&zend_extensions);
		    */
		    extension = &suhosin_zend_extension_entry;
		}
		module_entry_ptr->handle = NULL;

	} else {
		return FAILURE;
	}



	if (SUHOSIN_G(apc_bug_workaround)) {
		resid = zend_get_resource_handle(extension);
	}
	resid = zend_get_resource_handle(extension);
	suhosin_zend_extension_entry.resource_number = resid;

	suhosin_hook_treat_data();
	suhosin_hook_post_handlers(TSRMLS_C);
	suhosin_aes_gentables();
	suhosin_hook_register_server_variables();
	suhosin_hook_header_handler();
	suhosin_hook_execute(TSRMLS_C);
	suhosin_hook_session(TSRMLS_C);


	return SUCCESS;
}
Beispiel #3
0
/* {{{ PHP_INI_MH
 */
static PHP_INI_MH(suhosin_OnChangeMemoryLimit)
{
#if SIZEOF_LONG==8
	long hard_memory_limit = 0x7fffffffffffffff;
#elif SIZEOF_LONG==4
	long hard_memory_limit = 0x7fffffff;
#endif /* will produce a compile error or SIZEOF_LONG is not 4 or 8 */
	if (stage == ZEND_INI_STAGE_RUNTIME) {
		if (SUHOSIN_G(memory_limit) > 0) {
			SUHOSIN_G(hard_memory_limit) = SUHOSIN_G(memory_limit);
		} else if (SUHOSIN_G(hard_memory_limit) == 0) {
			SUHOSIN_G(hard_memory_limit) = PG(memory_limit);
		}
		hard_memory_limit = SUHOSIN_G(hard_memory_limit);
	} else {
		SUHOSIN_G(hard_memory_limit) = 0;
	}
	if (new_value) {
		PG(memory_limit) = zend_atol(new_value, new_value_length);
		if (hard_memory_limit > 0) {
			if (PG(memory_limit) > hard_memory_limit) {
				suhosin_log(S_MISC, "script tried to increase memory_limit to %lu bytes which is above the allowed value", PG(memory_limit));
				if (!SUHOSIN_G(simulation)) {
					PG(memory_limit) = hard_memory_limit;
					return FAILURE;
				}
			} else if (PG(memory_limit) < 0) {
				suhosin_log(S_MISC, "script tried to disable memory_limit by setting it to a negative value %ld bytes which is not allowed", PG(memory_limit));
				if (!SUHOSIN_G(simulation)) {
					PG(memory_limit) = hard_memory_limit;
					return FAILURE;
				}
			}
		}
	} else {
		PG(memory_limit) = hard_memory_limit;
	}
	return zend_set_memory_limit(PG(memory_limit));
}
Beispiel #4
0
/* {{{ SAPI_UPLOAD_VARNAME_FILTER_FUNC
 */
static int check_fileupload_varname(char *varname)
{
	char *index, *prev_index = NULL, *var;
	unsigned int var_len, total_len, depth = 0;
	TSRMLS_FETCH();

	var = estrdup(varname);

	/* Normalize the variable name */
	normalize_varname(var);
	
	/* Find length of variable name */
	index = strchr(var, '[');
	total_len = strlen(var);
	var_len = index ? index-var : total_len;
	
	/* Drop this variable if it exceeds the varname/total length limit */
	if (SUHOSIN_G(max_varname_length) && SUHOSIN_G(max_varname_length) < var_len) {
		suhosin_log(S_FILES, "configured request variable name length limit exceeded - dropped variable '%s'", var);
		if (!SUHOSIN_G(simulation)) {
			goto return_failure;
		}
	}
	if (SUHOSIN_G(max_totalname_length) && SUHOSIN_G(max_totalname_length) < total_len) {
		suhosin_log(S_FILES, "configured request variable total name length limit exceeded - dropped variable '%s'", var);
		if (!SUHOSIN_G(simulation)) {
			goto return_failure;
		}
	}
	if (SUHOSIN_G(max_post_name_length) && SUHOSIN_G(max_post_name_length) < var_len) {
		suhosin_log(S_FILES, "configured POST variable name length limit exceeded - dropped variable '%s'", var);
		if (!SUHOSIN_G(simulation)) {
			goto return_failure;
		}
	}
	if (SUHOSIN_G(max_post_totalname_length) && SUHOSIN_G(max_post_totalname_length) < var_len) {
		suhosin_log(S_FILES, "configured POST variable total name length limit exceeded - dropped variable '%s'", var);
		if (!SUHOSIN_G(simulation)) {
			goto return_failure;
		}
	}
	
	/* Find out array depth */
	while (index) {
		char *index_end;
		unsigned int index_length;
		
		/* overjump '[' */
		index++;
		
		/* increase array depth */
		depth++;
				
		index_end = strchr(index, ']');
		if (index_end == NULL) {
			index_end = index+strlen(index);
		}
		
		index_length = index_end - index;
			
		if (SUHOSIN_G(max_array_index_length) && SUHOSIN_G(max_array_index_length) < index_length) {
			suhosin_log(S_FILES, "configured request variable array index length limit exceeded - dropped variable '%s'", var);
			if (!SUHOSIN_G(simulation)) {
				goto return_failure;
			}
		} 
		if (SUHOSIN_G(max_post_array_index_length) && SUHOSIN_G(max_post_array_index_length) < index_length) {
			suhosin_log(S_FILES, "configured POST variable array index length limit exceeded - dropped variable '%s'", var);
			if (!SUHOSIN_G(simulation)) {
				goto return_failure;
			}
		} 
		
		index = strchr(index, '[');		
	}
	
	/* Drop this variable if it exceeds the array depth limit */
	if (SUHOSIN_G(max_array_depth) && SUHOSIN_G(max_array_depth) < depth) {
		suhosin_log(S_FILES, "configured request variable array depth limit exceeded - dropped variable '%s'", var);
		if (!SUHOSIN_G(simulation)) {
			goto return_failure;
		}
	}
	if (SUHOSIN_G(max_post_array_depth) && SUHOSIN_G(max_post_array_depth) < depth) {
		suhosin_log(S_FILES, "configured POST variable array depth limit exceeded - dropped variable '%s'", var);
		if (!SUHOSIN_G(simulation)) {
			goto return_failure;
		}
	}
	
	
	/* Drop this variable if it is one of GLOBALS, _GET, _POST, ... */
	/* This is to protect several silly scripts that do globalizing themself */
	
	if (is_protected_varname(var, var_len)) {
		suhosin_log(S_FILES, "tried to register forbidden variable '%s' through FILE variables", var);
		if (!SUHOSIN_G(simulation)) {
			goto return_failure;
		}
	}

	efree(var);
	return SUCCESS;
	
return_failure:
	efree(var);
	return FAILURE;	
}
Beispiel #5
0
PHP_SUHOSIN_API void suhosin_log(int loglevel, char *fmt, ...)
{
	int s, r, i=0, fd;
	long written, towrite;
	int getcaller=0;
	char *wbuf;
	struct timeval tv;
	time_t now;
	struct tm tm;
#if defined(AF_UNIX)
	struct sockaddr_un saun;
#endif
#ifdef PHP_WIN32
	LPTSTR strs[2];
	unsigned short etype;
	DWORD evid;
#endif
	char buf[5000];
	char error[5000];
	char *ip_address;
	char *fname;
	char *alertstring;
	int lineno;
	va_list ap;
	TSRMLS_FETCH();

#if PHP_VERSION_ID >= 50500
	getcaller = (loglevel & S_GETCALLER) == S_GETCALLER;
#endif
	/* remove the S_GETCALLER flag */
	loglevel = loglevel & ~S_GETCALLER;

	SDEBUG("(suhosin_log) loglevel: %d log_syslog: %u - log_sapi: %u - log_script: %u", loglevel, SUHOSIN_G(log_syslog), SUHOSIN_G(log_sapi), SUHOSIN_G(log_script));

	/* dump core if wanted */
	if (SUHOSIN_G(coredump) && loglevel == S_MEMORY) {
		volatile unsigned int *x = 0;
		volatile int y = *x;
	}
	
	if (SUHOSIN_G(log_use_x_forwarded_for)) {
		ip_address = suhosin_getenv("HTTP_X_FORWARDED_FOR", 20 TSRMLS_CC);
		if (ip_address == NULL) {
			ip_address = "X-FORWARDED-FOR not set";
		}
	} else {
		ip_address = suhosin_getenv("REMOTE_ADDR", 11 TSRMLS_CC);
		if (ip_address == NULL) {
			ip_address = "REMOTE_ADDR not set";
		}
	}
	
	
	va_start(ap, fmt);
	ap_php_vsnprintf(error, sizeof(error), fmt, ap);
	va_end(ap);
	while (error[i]) {
		if (error[i] < 32) error[i] = '.';
		i++;
	}
	
	if (SUHOSIN_G(simulation)) {
		alertstring = "ALERT-SIMULATION";
	} else {
		alertstring = "ALERT";
	}
	
	if (zend_is_executing(TSRMLS_C)) {
		zend_execute_data *exdata = EG(current_execute_data);
		if (exdata) {
			if (getcaller && exdata->prev_execute_data) {
				lineno = exdata->prev_execute_data->opline->lineno;
				fname = (char *)exdata->prev_execute_data->op_array->filename;									
			} else {
				lineno = exdata->opline->lineno;
				fname = (char *)exdata->op_array->filename;				
			}
		} else {
			lineno = zend_get_executed_lineno(TSRMLS_C);
			fname = (char *)zend_get_executed_filename(TSRMLS_C);
		}
		ap_php_snprintf(buf, sizeof(buf), "%s - %s (attacker '%s', file '%s', line %u)", alertstring, error, ip_address, fname, lineno);
	} else {
		fname = suhosin_getenv("SCRIPT_FILENAME", 15 TSRMLS_CC);
		if (fname==NULL) {
			fname = "unknown";
		}
		ap_php_snprintf(buf, sizeof(buf), "%s - %s (attacker '%s', file '%s')", alertstring, error, ip_address, fname);
	}
			
	/* Syslog-Logging disabled? */
	if (((SUHOSIN_G(log_syslog)|S_INTERNAL) & loglevel)==0) {
		goto log_file;
	}	
	
#if defined(AF_UNIX)
	ap_php_snprintf(error, sizeof(error), "<%u>suhosin[%u]: %s\n", (unsigned int)(SUHOSIN_G(log_syslog_facility)|SUHOSIN_G(log_syslog_priority)),getpid(),buf);

	s = socket(AF_UNIX, SOCK_DGRAM, 0);
	if (s == -1) {
		goto log_file;
	}
	
	memset(&saun, 0, sizeof(saun));
	saun.sun_family = AF_UNIX;
	strcpy(saun.sun_path, SYSLOG_PATH);
	/*saun.sun_len = sizeof(saun);*/
	
	r = connect(s, (struct sockaddr *)&saun, sizeof(saun));
	if (r) {
		close(s);
    		s = socket(AF_UNIX, SOCK_STREAM, 0);
		if (s == -1) {
			goto log_file;
		}
	
		memset(&saun, 0, sizeof(saun));
		saun.sun_family = AF_UNIX;
		strcpy(saun.sun_path, SYSLOG_PATH);
		/*saun.sun_len = sizeof(saun);*/

		r = connect(s, (struct sockaddr *)&saun, sizeof(saun));
		if (r) { 
			close(s);
			goto log_file;
		}
	}
	send(s, error, strlen(error), 0);
	
	close(s);
#endif
#ifdef PHP_WIN32
	ap_php_snprintf(error, sizeof(error), "suhosin[%u]: %s", getpid(),buf);

	switch (SUHOSIN_G(log_syslog_priority)) {			/* translate UNIX type into NT type */
		case 1: /*LOG_ALERT:*/
			etype = EVENTLOG_ERROR_TYPE;
			break;
		case 6: /*LOG_INFO:*/
			etype = EVENTLOG_INFORMATION_TYPE;
			break;
		default:
			etype = EVENTLOG_WARNING_TYPE;
	}
	evid = loglevel;
	strs[0] = error;
	/* report the event */
	if (log_source == NULL) {
		log_source = RegisterEventSource(NULL, "Suhosin-" SUHOSIN_EXT_VERSION);
	}
	ReportEvent(log_source, etype, (unsigned short) SUHOSIN_G(log_syslog_priority), evid, NULL, 1, 0, strs, NULL);
	
#endif
log_file:
	/* File-Logging disabled? */
	if ((SUHOSIN_G(log_file) & loglevel)==0) {
		goto log_sapi;
	}
	
	if (!SUHOSIN_G(log_filename) || !SUHOSIN_G(log_filename)[0]) {
		goto log_sapi;
	}
	fd = open(SUHOSIN_G(log_filename), O_CREAT|O_APPEND|O_WRONLY, 0640);
	if (fd == -1) {
	    suhosin_log(S_INTERNAL, "Unable to open logfile: %s", SUHOSIN_G(log_filename));
	    return;
	}

	gettimeofday(&tv, NULL);
	now = tv.tv_sec;
	php_gmtime_r(&now, &tm);
	ap_php_snprintf(error, sizeof(error), "%s %2d %02d:%02d:%02d [%u] %s\n", month_names[tm.tm_mon], tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec, getpid(),buf);
	towrite = strlen(error);
	wbuf = error;
	php_flock(fd, LOCK_EX);
	while (towrite > 0) {
		written = write(fd, wbuf, towrite);
		if (written < 0) {
			break;
		}
		towrite -= written;
		wbuf += written;
	}
	php_flock(fd, LOCK_UN);
	close(fd);

log_sapi:
	/* SAPI Logging activated? */
	SDEBUG("(suhosin_log) log_syslog: %u - log_sapi: %u - log_script: %u - log_phpscript: %u", SUHOSIN_G(log_syslog), SUHOSIN_G(log_sapi), SUHOSIN_G(log_script), SUHOSIN_G(log_phpscript));
	if (((SUHOSIN_G(log_sapi)|S_INTERNAL) & loglevel)!=0) {
#if PHP_VERSION_ID < 50400
		sapi_module.log_message(buf);
#else
		sapi_module.log_message(buf TSRMLS_CC);
#endif
	}
	if ((SUHOSIN_G(log_stdout) & loglevel)!=0) {
		printf("%s\n", buf);
	}

/*log_script:*/
	/* script logging activaed? */
	if (((SUHOSIN_G(log_script) & loglevel)!=0) && SUHOSIN_G(log_scriptname)!=NULL) {
		char cmd[8192], *cmdpos, *bufpos;
		FILE *in;
		int space;
		struct stat st;
		
		char *sname = SUHOSIN_G(log_scriptname);
		while (isspace(*sname)) ++sname;
		if (*sname == 0) goto log_phpscript;
		
		if (VCWD_STAT(sname, &st) < 0) {
			suhosin_log(S_INTERNAL, "unable to find logging shell script %s - file dropped", sname);
			goto log_phpscript;
		}
		if (access(sname, X_OK|R_OK) < 0) {
			suhosin_log(S_INTERNAL, "logging shell script %s is not executable - file dropped", sname);
			goto log_phpscript;					
		}
		
		/* TODO: clean up this code to calculate size of output dynamically */
		ap_php_snprintf(cmd, sizeof(cmd) - 20, "%s %s \'", sname, loglevel2string(loglevel));
		space = sizeof(cmd) - strlen(cmd) - 20;
		cmdpos = cmd + strlen(cmd);
		bufpos = buf;
		if (space <= 1) return;
		while (space > 2 && *bufpos) {
			if (*bufpos == '\'') {
				if (space<=5) break;
				*cmdpos++ = '\'';
				*cmdpos++ = '\\';
				*cmdpos++ = '\'';
				*cmdpos++ = '\'';
				bufpos++;
				space-=4;
			} else {
				*cmdpos++ = *bufpos++;
				space--;
			}
		}
		*cmdpos++ = '\'';
		*cmdpos++ = ' ';
		*cmdpos++ = '2';
		*cmdpos++ = '>';
		*cmdpos++ = '&';
		*cmdpos++ = '1';
		*cmdpos = 0;
		
		if ((in=VCWD_POPEN(cmd, "r"))==NULL) {
			suhosin_log(S_INTERNAL, "Unable to execute logging shell script: %s", sname);
			goto log_phpscript;
		}
		/* read and forget the result */
		while (1) {
			int readbytes = fread(cmd, 1, sizeof(cmd), in);
			if (readbytes<=0) {
				break;
			}
			if (strncmp(cmd, "sh: ", 4) == 0) {
				/* assume this is an error */
				suhosin_log(S_INTERNAL, "Error while executing logging shell script: %s", sname);
				pclose(in);
				goto log_phpscript;
			}
		}
		pclose(in);
	}
log_phpscript:
	if ((SUHOSIN_G(log_phpscript) & loglevel)!=0 && EG(in_execution) && SUHOSIN_G(log_phpscriptname) && SUHOSIN_G(log_phpscriptname)[0]) {
		zend_file_handle file_handle;
		zend_op_array *new_op_array;
		zval *result = NULL;
		
		long orig_execution_depth = SUHOSIN_G(execution_depth);
#if PHP_VERSION_ID < 50400
		zend_bool orig_safe_mode = PG(safe_mode);
#endif
		char *orig_basedir = PG(open_basedir);
		
		char *phpscript = SUHOSIN_G(log_phpscriptname);
SDEBUG("scriptname %s", SUHOSIN_G(log_phpscriptname));				
#ifdef ZEND_ENGINE_2
		if (zend_stream_open(phpscript, &file_handle TSRMLS_CC) == SUCCESS) {
#else
		if (zend_open(phpscript, &file_handle) == SUCCESS && ZEND_IS_VALID_FILE_HANDLE(&file_handle)) {
			file_handle.filename = phpscript;
			file_handle.free_filename = 0;
#endif		
			if (!file_handle.opened_path) {
				file_handle.opened_path = estrndup(phpscript, strlen(phpscript));
			}
			new_op_array = zend_compile_file(&file_handle, ZEND_REQUIRE TSRMLS_CC);
			zend_destroy_file_handle(&file_handle TSRMLS_CC);
			if (new_op_array) {
				HashTable *active_symbol_table = EG(active_symbol_table);
				zval *zerror, *zerror_class;
				
				if (active_symbol_table == NULL) {
					active_symbol_table = &EG(symbol_table);
				}
				EG(return_value_ptr_ptr) = &result;
				EG(active_op_array) = new_op_array;
				
				MAKE_STD_ZVAL(zerror);
				MAKE_STD_ZVAL(zerror_class);
				ZVAL_STRING(zerror, buf, 1);
				ZVAL_LONG(zerror_class, loglevel);

				zend_hash_update(active_symbol_table, "SUHOSIN_ERROR", sizeof("SUHOSIN_ERROR"), (void **)&zerror, sizeof(zval *), NULL);
				zend_hash_update(active_symbol_table, "SUHOSIN_ERRORCLASS", sizeof("SUHOSIN_ERRORCLASS"), (void **)&zerror_class, sizeof(zval *), NULL);
				
				SUHOSIN_G(execution_depth) = 0;
				if (SUHOSIN_G(log_phpscript_is_safe)) {
#if PHP_VERSION_ID < 50400
					PG(safe_mode) = 0;
#endif
					PG(open_basedir) = NULL;
				}
				
				zend_execute(new_op_array TSRMLS_CC);
				
				SUHOSIN_G(execution_depth) = orig_execution_depth;
#if PHP_VERSION_ID < 50400				
				PG(safe_mode) = orig_safe_mode;
#endif
				PG(open_basedir) = orig_basedir;
				
#ifdef ZEND_ENGINE_2
				destroy_op_array(new_op_array TSRMLS_CC);
#else
				destroy_op_array(new_op_array);
#endif
				efree(new_op_array);
#ifdef ZEND_ENGINE_2
				if (!EG(exception))
#endif			
				{
					if (EG(return_value_ptr_ptr)) {
						zval_ptr_dtor(EG(return_value_ptr_ptr));
						EG(return_value_ptr_ptr) = NULL;
					}
				}
			} else {
				suhosin_log(S_INTERNAL, "Unable to execute logging PHP script: %s", SUHOSIN_G(log_phpscriptname));
				return;
			}
		} else {
			suhosin_log(S_INTERNAL, "Unable to execute logging PHP script: %s", SUHOSIN_G(log_phpscriptname));
			return;
		}
	}

}
Beispiel #6
0
static int suhosin_check_filename(char *s, int len TSRMLS_DC)
{
	char fname[MAXPATHLEN+1];
	char *t, *h, *h2, *index, *e;
	int tlen, i, count=0;
	uint indexlen;
	ulong numindex;
	zend_bool isOk;

	/* check if filename is too long */
	if (len > MAXPATHLEN) {
		return SUHOSIN_CODE_TYPE_LONGNAME;
	}
	memcpy(fname, s, len);
	fname[len] = 0; 
	s = (char *)&fname;
	e = s + len;

	/* check if ASCIIZ attack -> not working yet (and cannot work in PHP4 + ZO) */
	if (len != strlen(s)) {
		return SUHOSIN_CODE_TYPE_0FILE;
	}
	
	/* disallow uploaded files */
	if (SG(rfc1867_uploaded_files)) {
		if (zend_hash_exists(SG(rfc1867_uploaded_files), (char *) s, e-s+1)) {
			return SUHOSIN_CODE_TYPE_UPLOADED;
		}
	}
		
	/* count number of directory traversals */
	for (i=0; i < len-3; i++) {
		if (s[i] == '.' && s[i+1] == '.' && (s[i+2] == '/' || s[i+2] == '\\')) {
			count++;
			i+=2;
		}
	}
	if (SUHOSIN_G(executor_include_max_traversal) && SUHOSIN_G(executor_include_max_traversal)<=count) {
		return SUHOSIN_CODE_TYPE_MANYDOTS;
	}
	
SDEBUG("xxx %08x %08x",SUHOSIN_G(include_whitelist),SUHOSIN_G(include_blacklist));
	/* no black or whitelist then disallow all */
	if (SUHOSIN_G(include_whitelist)==NULL && SUHOSIN_G(include_blacklist)==NULL) {
		/* disallow all URLs */
		if (strstr(s, "://") != NULL || suhosin_strcasestr(s, "data:") != NULL) {
			return SUHOSIN_CODE_TYPE_BADURL;
		}
	} else 
	/* whitelist is stronger than blacklist */
	if (SUHOSIN_G(include_whitelist)) {
		
		do {
			isOk = 0;
			
			h = strstr(s, "://");
			h2 = suhosin_strcasestr(s, "data:");
			h2 = h2 == NULL ? NULL : h2 + 4;
			t = h = (h == NULL) ? h2 : ( (h2 == NULL) ? h : ( (h < h2) ? h : h2 ) );
			if (h == NULL) break;
							
			while (t > s && (isalnum(t[-1]) || t[-1]=='_' || t[-1]=='.')) {
				t--;
			}
			
			tlen = e-t;
			
			zend_hash_internal_pointer_reset(SUHOSIN_G(include_whitelist));
			do {
				int r = zend_hash_get_current_key_ex(SUHOSIN_G(include_whitelist), &index, &indexlen, &numindex, 0, NULL);
				
				if (r==HASH_KEY_NON_EXISTANT) {
					break;
				}
				if (r==HASH_KEY_IS_STRING) {
					if (h-t <= indexlen-1 && tlen>=indexlen-1) {
						if (strncasecmp(t, index, indexlen-1)==0) {
							isOk = 1;
							break;
						}
					}
				}
				
				zend_hash_move_forward(SUHOSIN_G(include_whitelist));
			} while (1);
			
			/* not found in whitelist */
			if (!isOk) {
				return SUHOSIN_CODE_TYPE_BADURL;
			}
			
			s = h + 1;
		} while (1);
	} else {
		
		do {
			int tlen;
			
			h = strstr(s, "://");
			h2 = suhosin_strcasestr(s, "data:");
			h2 = h2 == NULL ? NULL : h2 + 4;
			t = h = (h == NULL) ? h2 : ( (h2 == NULL) ? h : ( (h < h2) ? h : h2 ) );
			if (h == NULL) break;
							
			while (t > s && (isalnum(t[-1]) || t[-1]=='_' || t[-1]=='.')) {
				t--;
			}

			tlen = e-t;

			zend_hash_internal_pointer_reset(SUHOSIN_G(include_blacklist));
			do {
				int r = zend_hash_get_current_key_ex(SUHOSIN_G(include_blacklist), &index, &indexlen, &numindex, 0, NULL);

				if (r==HASH_KEY_NON_EXISTANT) {
					break;
				}
				if (r==HASH_KEY_IS_STRING) {
					if (h-t <= indexlen-1 && tlen>=indexlen-1) {
						if (strncasecmp(t, index, indexlen-1)==0) {
							return SUHOSIN_CODE_TYPE_BLACKURL;
						}
					}
				}
				
				zend_hash_move_forward(SUHOSIN_G(include_blacklist));
			} while (1);
			
			s = h + 1;
		} while (1);
	}

	/* disallow writable files */
	if (!SUHOSIN_G(executor_include_allow_writable_files)) {
	        /* protection against *REMOTE* attacks, potential
	           race condition of access() is irrelevant */
	        if (access(s, W_OK) == 0) {
                        return SUHOSIN_CODE_TYPE_WRITABLE;
	        }
	}

	return SUHOSIN_CODE_TYPE_GOODFILE;
}
Beispiel #7
0
static ZEND_INI_MH(OnUpdateSuhosin_perdir)
{
        char *tmp;

	if (SUHOSIN_G(perdir)) {
    		pefree(SUHOSIN_G(perdir), 1);
	}
	SUHOSIN_G(perdir) = NULL;
    
        /* Initialize the perdir flags */
        SUHOSIN_G(log_perdir) = 0;
        SUHOSIN_G(exec_perdir) = 0;
        SUHOSIN_G(get_perdir) = 0;
        SUHOSIN_G(cookie_perdir) = 0;
        SUHOSIN_G(post_perdir) = 0;
        SUHOSIN_G(request_perdir) = 0;
        SUHOSIN_G(sql_perdir) = 0;
        SUHOSIN_G(upload_perdir) = 0;
        SUHOSIN_G(misc_perdir) = 0;
    
	if (new_value == NULL) {
		return SUCCESS;
	}
	
        tmp = SUHOSIN_G(perdir) = pestrdup(new_value,1);
        
        /* trim the whitespace */
        while (isspace(*tmp)) tmp++;
        
        /* should we deactivate perdir completely? */
        if (*tmp == 0 || *tmp == '0') {
            return SUCCESS;
        }
        
        /* no deactivation so check the flags */
        while (*tmp) {
            switch (*tmp) {
                case 'l':
                case 'L':
                    SUHOSIN_G(log_perdir) = 1;
                    break;
                case 'e':
                case 'E':
                    SUHOSIN_G(exec_perdir) = 1;
                    break;
                case 'g':
                case 'G':
                    SUHOSIN_G(get_perdir) = 1;
                    break;
                case 'c':
                case 'C':
                    SUHOSIN_G(cookie_perdir) = 1;
                    break;
                case 'p':
                case 'P':
                    SUHOSIN_G(post_perdir) = 1;
                    break;
                case 'r':
                case 'R':
                    SUHOSIN_G(request_perdir) = 1;
                    break;
                case 's':
                case 'S':
                    SUHOSIN_G(sql_perdir) = 1;
                    break;
                case 'u':
                case 'U':
                    SUHOSIN_G(upload_perdir) = 1;
                    break;
                case 'm':
                case 'M':
                    SUHOSIN_G(misc_perdir) = 1;
                    break;
            }
            tmp++;
        }        
	return SUCCESS;
}