[PATCH] Support hash randomization

107 views
Skip to first unread message

Luke Macken

unread,
Mar 1, 2012, 4:59:24 PM3/1/12
to mod...@googlegroups.com
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

mod_wsgi-hash-randomization.patch

Graham Dumpleton

unread,
Mar 1, 2012, 5:43:08 PM3/1/12
to mod...@googlegroups.com
I am not sure about making it default.

The problem with something like mod_wsgi is it is actually very hard
to ever change the existing defaults, even if a new feature could be
better.

This is because you simply can't risk upsetting existing users code in
ways they don't expect.

The need to stay with defaults is therefore a pain at times, because
we know people don't read documentation and so work out that they
should turn on optional features for better performance, stability,
security etc.

I might be prepared to break with that, but only if Python 3.X since
not as many people would be using mod_wsgi there. IOW, off by default
for Python 2.X and on by default for 3.X, but even that carries risk
as people will eventually port code across and find problems then.

Graham

Luke Macken

unread,
Mar 1, 2012, 6:53:23 PM3/1/12
to mod...@googlegroups.com
On Fri, Mar 02, 2012 at 09:43:08AM +1100, Graham Dumpleton wrote:
> I am not sure about making it default.

Completely understandable.

> I might be prepared to break with that, but only if Python 3.X since
> not as many people would be using mod_wsgi there. IOW, off by default
> for Python 2.X and on by default for 3.X, but even that carries risk
> as people will eventually port code across and find problems then.

This sounds reasonable to me.

Attached is a patch that disables WSGIHashRandomization by default.

luke

mod_wsgi-hash-randomization.patch

Luke Macken

unread,
Apr 12, 2012, 3:00:18 PM4/12/12
to mod...@googlegroups.com
Ping?

Python 2.6.8, 2.7.3, 3.1.5, and 3.2.3 are now out, which support hash
randomization. My patch also works fine with all previous versions.

It would be nice to get this feature into mod_wsgi so people can secure
their webapps (without having to hack up their apache init scripts).

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 = 0;
> +#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 }
> };
>

Reply all
Reply to author
Forward
0 new messages