Hello, As of 2.6.8, 2.7.3 and 3.2.3, Python supports hash seed randomization. See http://bugs.python.org/issue13703 for details.
It's off by default, except in 3.3+, and can be enabled via the PYTHONHASHSEED=random environment variable, the -R command-line flag, or by flipping the Py_HashRandomizationFlag flag in C before Python is initialized. Since we cannot alter the os.environ via Apache directives, like SetEnv, I thought it would make sense to make a mod_wsgi configuration option for this. Attached is a patch that adds a WSGIHashRandomization configuration directive. I tested the patch and can confirm that `sys.flags.hash_randomization` reflects that it is getting properly enabled in my application. Right now the patch enables this feature by default, if it's available. This behavior is obviously up for discussion, as it may break code that makes assumptions about dictionary ordering and such (as seen in some stdlib unit tests that broke). However, for security purposes, I think everyone will want this feature turned on by default. Cheers, luke
diff -up ./configure.ac.orig ./configure.ac
--- ./configure.ac.orig 2009-11-23 01:49:39.000000000 -0500
+++ ./configure.ac 2012-03-01 16:07:15.211953095 -0500
@@ -92,6 +92,16 @@ else
CPPFLAGS3=""
fi
+AC_MSG_CHECKING(Python hash randomization support)
+PYTHON_HASH_RANDOMIZATION=`${PYTHON} -c 'from sys import flags, stdout; \
+ stdout.write(str(getattr(flags, "hash_randomization", "")))'`
+if test -n "${PYTHON_HASH_RANDOMIZATION}"; then
+ CPPFLAGS3="${CPPFLAGS3} -DWITH_PYTHON_HASH_RANDOMIZATION"
+ AC_MSG_RESULT(yes)
+else
+ AC_MSG_RESULT(no)
+fi
+
CPPFLAGS="${CPPFLAGS} ${CPPFLAGS1} ${CPPFLAGS2} ${CPPFLAGS3}"
AC_SUBST(CPPFLAGS)
diff -up ./mod_wsgi.c.orig ./mod_wsgi.c
--- ./mod_wsgi.c.orig 2010-07-25 23:58:37.000000000 -0400
+++ ./mod_wsgi.c 2012-03-01 16:05:33.225451743 -0500
@@ -479,6 +479,10 @@ typedef struct {
int error_override;
int chunked_request;
+#ifdef WITH_PYTHON_HASH_RANDOMIZATION
+ int hash_randomization;
+#endif
+
#if AP_SERVER_MAJORVERSION_NUMBER >= 2
apr_hash_t *handler_scripts;
#endif
@@ -532,6 +536,10 @@ static WSGIServerConfig *newWSGIServerCo
object->restrict_stdout = -1;
object->restrict_signal = -1;
+#ifdef WITH_PYTHON_HASH_RANDOMIZATION
+ object->hash_randomization = -1;
+#endif
+
#if defined(WIN32) || defined(DARWIN)
object->case_sensitivity = 0;
#else
@@ -5810,6 +5818,12 @@ static void wsgi_python_init(apr_pool_t
_wputenv(L"PYTHONIOENCODING=cp1252:backslashreplace");
#endif
+#ifdef WITH_PYTHON_HASH_RANDOMIZATION
+ if (wsgi_server_config->hash_randomization != 0) {
+ Py_HashRandomizationFlag = 1;
+ }
+#endif
+
/* Initialise Python. */
ap_log_error(APLOG_MARK, WSGI_LOG_INFO(0), wsgi_server,
@@ -7328,6 +7342,30 @@ static const char *wsgi_set_restrict_sig
return NULL;
}
+#ifdef WITH_PYTHON_HASH_RANDOMIZATION
+static const char *wsgi_set_hash_randomization(cmd_parms *cmd, void *mconfig,
+ const char *f)
+{
+ const char *error = NULL;
+ WSGIServerConfig *sconfig = NULL;
+
+ error = ap_check_cmd_context(cmd, GLOBAL_ONLY);
+ if (error != NULL)
+ return error;
+
+ sconfig = ap_get_module_config(cmd->server->module_config, &wsgi_module);
+
+ if (strcasecmp(f, "Off") == 0)
+ sconfig->hash_randomization = 0;
+ else if (strcasecmp(f, "On") == 0)
+ sconfig->hash_randomization = 1;
+ else
+ return "WSGIHashRandomization must be one of: Off | On";
+
+ return NULL;
+}
+#endif
+
static const char *wsgi_set_case_sensitivity(cmd_parms *cmd, void *mconfig,
const char *f)
{
@@ -9232,6 +9270,11 @@ static const command_rec wsgi_commands[]
{ "WSGIChunkedRequest", wsgi_set_chunked_request, NULL,
OR_FILEINFO, TAKE1, "Enable/Disable support for chunked request." },
+#ifdef WITH_PYTHON_HASH_RANDOMIZATION
+ { "WSGIHashRandomization", wsgi_set_hash_randomization, NULL,
+ RSRC_CONF, TAKE1, "Enable/Disable hash randomization" },
+#endif
+
{ NULL }
};
@@ -14951,6 +14994,11 @@ static const command_rec wsgi_commands[]
AP_INIT_RAW_ARGS("WSGIHandlerScript", wsgi_add_handler_script,
NULL, ACCESS_CONF|RSRC_CONF, "Location of WSGI handler script file."),
+#ifdef WITH_PYTHON_HASH_RANDOMIZATION
+ AP_INIT_RAW_ARGS("WSGIHashRandomization", wsgi_set_hash_randomization,
+ NULL, RSRC_CONF, "Enable/Disable hash randomization."),
+#endif
+
{ NULL }
};
pgpVdtVodOqPs.pgp
Description: PGP signature
