From 0c2aac95f8df4e7c243ea00d54d4050e32f7868b Mon Sep 17 00:00:00 2001
From: Alexander Chernyakhovsky <achernya@mit.edu>
Date: Fri, 3 May 2013 21:39:17 -0400
Subject: [PATCH 2/4] Prevent mod_status from taking effect in .htaccess files

Introduce a directive to the Apache configuration that is only
permitted in a directory context, called "PermitStatusHandler", to
prevent users from enabling mod_status from their .htaccess files.

Signed-off-by: Quentin Smith <quentin@mit.edu>
Signed-off-by: Geoffrey Thomas <geofft@mit.edu>
---
 modules/generators/mod_status.c |   60 +++++++++++++++++++++++++++++++++++++--
 1 file changed, 57 insertions(+), 3 deletions(-)

diff --git a/modules/generators/mod_status.c b/modules/generators/mod_status.c
index 0237f1d..c7fd0e0 100644
--- a/modules/generators/mod_status.c
+++ b/modules/generators/mod_status.c
@@ -103,6 +103,56 @@ APR_IMPLEMENT_OPTIONAL_HOOK_RUN_ALL(ap, STATUS, int, status_hook,
 static pid_t child_pid;
 #endif
 
+typedef struct {
+  int permit_status_handler;
+} status_config_rec;
+
+/*
+ * command-related code. This is here to prevent use of ExtendedStatus
+ * without status_module included.
+ */
+static const char *set_extended_status(cmd_parms *cmd, void *dummy, int arg)
+{
+    const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
+    if (err != NULL) {
+        return err;
+    }
+    ap_extended_status = arg;
+    return NULL;
+}
+
+static const char *set_reqtail(cmd_parms *cmd, void *dummy, int arg)
+{
+    const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
+    if (err != NULL) {
+        return err;
+    }
+    ap_mod_status_reqtail = arg;
+    return NULL;
+}
+
+static void *create_status_dir_config(apr_pool_t *p, char *d)
+{
+  status_config_rec *conf = apr_pcalloc(p, sizeof(*conf));
+  conf->permit_status_handler = 0;
+  return conf;
+}
+
+static const command_rec status_module_cmds[] =
+{
+    AP_INIT_FLAG("ExtendedStatus", set_extended_status, NULL, RSRC_CONF,
+      "\"On\" to enable extended status information, \"Off\" to disable"),
+    AP_INIT_FLAG("SeeRequestTail", set_reqtail, NULL, RSRC_CONF,
+      "For verbose requests, \"On\" to see the last 63 chars of the request, "
+      "\"Off\" (default) to see the first 63 in extended status display"),
+    AP_INIT_FLAG("PermitStatusHandler", ap_set_flag_slot,
+		 (void *)APR_OFFSETOF(status_config_rec, permit_status_handler),
+		 ACCESS_CONF,
+      "As a security measure, only permit status handlers where this flag "
+      "is set. Only legal in directory context, not .htaccess."),
+    {NULL}
+};
+
 /* Format the number of bytes nicely */
 static void format_byte_out(request_rec *r, apr_off_t bytes)
 {
@@ -207,8 +257,12 @@ static int status_handler(request_rec *r)
     int times_per_thread;
 #endif
 
-    if (strcmp(r->handler, STATUS_MAGIC_TYPE) && strcmp(r->handler,
-            "server-status")) {
+    status_config_rec *conf = ap_get_module_config(r->per_dir_config,
+						   &status_module);
+
+    if ((strcmp(r->handler, STATUS_MAGIC_TYPE) &&
+         strcmp(r->handler, "server-status")) ||
+	!conf->permit_status_handler) {
         return DECLINED;
     }
 
@@ -974,7 +1028,7 @@ static void register_hooks(apr_pool_t *p)
 AP_DECLARE_MODULE(status) =
 {
     STANDARD20_MODULE_STUFF,
-    NULL,                       /* dir config creater */
+    create_status_dir_config,   /* dir config creater */
     NULL,                       /* dir merger --- default is to override */
     NULL,                       /* server config */
     NULL,                       /* merge server config */
-- 
1.7.9.6 (Apple Git-31.1)

