]> git.ipfire.org Git - thirdparty/apache/httpd.git/commitdiff
Merge r1935016 from trunk:
authorEric Covener <covener@apache.org>
Fri, 5 Jun 2026 10:28:53 +0000 (10:28 +0000)
committerEric Covener <covener@apache.org>
Fri, 5 Jun 2026 10:28:53 +0000 (10:28 +0000)
restrict per-dir file funcs centrally

Reviewed By: covener, jorton, jfclere

git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.4.x@1935017 13f79535-47bb-0310-9956-ffa450edef68

include/ap_expr.h
modules/mappers/mod_rewrite.c
modules/metadata/mod_setenvif.c
modules/proxy/mod_proxy_fcgi.c
server/util_expr_eval.c

index 8e57fcdadcce037ad46c9b3720969f939816b0f2..16138c9f6cd2f62f53e3edc0a87c0b8a58fdc818 100644 (file)
@@ -66,6 +66,8 @@ typedef struct {
 #define AP_EXPR_FLAG_RESTRICTED            4
 /** Expression evaluates to a string, not to a bool */
 #define AP_EXPR_FLAG_STRING_RESULT         8
+/** Don't allow functions/vars that expose content from the filesystem. */
+#define AP_EXPR_FLAG_RESTRICTED_FILE_FUNC   16
 
 
 /**
index 9b1c5b4b6ad13d2a820d637e061e93eb88175d2c..f1bc03cb2eef5be9f46e397775367644f237d2d7 100644 (file)
@@ -3682,8 +3682,6 @@ static const char *cmd_rewritecond(cmd_parms *cmd, void *in_dconf,
         int in_htaccess = cmd->pool == cmd->temp_pool;
         unsigned int flags = newcond->flags & CONDFLAG_NOVARY ?
                              AP_EXPR_FLAG_DONT_VARY : 0;
-        /* Use restricted ap_expr() parser in htaccess context. */
-        if (in_htaccess) flags |= AP_EXPR_FLAG_RESTRICTED;
         newcond->expr = ap_expr_parse_cmd(cmd, a2, flags, &err, NULL);
         if (err)
             return apr_psprintf(cmd->pool, "RewriteCond: cannot compile "
index b74c9c07dd92d8b668b1b39e87cc5d8c4ad486cc..0f44e0d01b3e688dd27681fea9cf79c7e402b906 100644 (file)
@@ -424,11 +424,6 @@ static const char *add_setenvifexpr(cmd_parms *cmd, void *mconfig,
     const char *err;
     unsigned int flags = 0;
 
-    /* Use restricted ap_expr() parser in htaccess context. */
-    if (cmd->pool == cmd->temp_pool) {
-        flags |= AP_EXPR_FLAG_RESTRICTED;
-    }
-
     /*
      * Determine from our context into which record to put the entry.
      * cmd->path == NULL means we're in server-wide context; otherwise,
index ef090ddc771e2ce18f630baf235f7e232fe43704..82e0c1e421834f646e550bc5f019cd784c2d0dfa 100644 (file)
@@ -1340,11 +1340,6 @@ static const char *cmd_setenv(cmd_parms *cmd, void *in_dconf,
     const char *envvar = arg2;
     unsigned int flags = 0;
 
-    /* Use restricted ap_expr() parser in htaccess context. */
-    if (cmd->pool == cmd->temp_pool) {
-        flags |= AP_EXPR_FLAG_RESTRICTED;
-    }
-
     new = apr_array_push(dconf->env_fixups);
     new->cond = ap_expr_parse_cmd(cmd, arg1, flags, &err, NULL);
     if (err) {
index 038d5a06d7896e4dbd58a8e442e4d96db5116dd7..d4cbf92c76ee4f2f3f38603948a90c6eb424e900 100644 (file)
@@ -437,6 +437,12 @@ AP_DECLARE(ap_expr_info_t*) ap_expr_parse_cmd_mi(const cmd_parms *cmd,
     info->line_number = cmd->directive->line_num;
     info->flags = flags;
     info->module_index = module_index;
+
+    /* Use restricted-contents ap_expr() parser in htaccess context. */
+    if (cmd->pool == cmd->temp_pool) {
+        info->flags |= AP_EXPR_FLAG_RESTRICTED_FILE_FUNC;
+    }
+
     *err = ap_expr_parse(cmd->pool, cmd->temp_pool, info, expr, lookup_fn);
 
     if (*err)
@@ -1661,11 +1667,15 @@ static int op_strcmatch(ap_expr_eval_ctx_t *ctx, const void *data,
     return (APR_SUCCESS == apr_fnmatch(arg2, arg1, APR_FNM_CASE_BLIND));
 }
 
+#define RESTRICTED_FILE_TEST 0x01
+#define RESTRICTED_FILE_FUNC 0x02
+#define RESTRICTED_ALL      (RESTRICTED_FILE_TEST | RESTRICTED_FILE_FUNC)
+
 struct expr_provider_single {
     const void *func;
     const char *name;
     ap_expr_lookup_fn_t *arg_parsing_func;
-    int restricted;
+    unsigned int restricted;
 };
 
 struct expr_provider_multi {
@@ -1695,8 +1705,8 @@ static const struct expr_provider_single string_func_providers[] = {
     { toupper_func,         "toupper",        NULL, 0 },
     { escape_func,          "escape",         NULL, 0 },
     { unescape_func,        "unescape",       NULL, 0 },
-    { file_func,            "file",           NULL, 1 },
-    { filesize_func,        "filesize",       NULL, 1 },
+    { file_func,            "file",           NULL, RESTRICTED_FILE_FUNC },
+    { filesize_func,        "filesize",       NULL, RESTRICTED_FILE_FUNC },
     { base64_func,          "base64",         NULL, 0 },
     { unbase64_func,        "unbase64",       NULL, 0 },
     { sha1_func,            "sha1",           NULL, 0 },
@@ -1712,13 +1722,13 @@ static const struct expr_provider_single unary_op_providers[] = {
     { op_nz,        "z", NULL,             0 },
     { op_R,         "R", subnet_parse_arg, 0 },
     { op_T,         "T", NULL,             0 },
-    { op_file_min,  "d", NULL,             1 },
-    { op_file_min,  "e", NULL,             1 },
-    { op_file_min,  "f", NULL,             1 },
-    { op_file_min,  "s", NULL,             1 },
-    { op_file_link, "L", NULL,             1 },
-    { op_file_link, "h", NULL,             1 },
-    { op_file_xbit, "x", NULL,             1 },
+    { op_file_min,  "d", NULL,             RESTRICTED_FILE_TEST },
+    { op_file_min,  "e", NULL,             RESTRICTED_FILE_TEST },
+    { op_file_min,  "f", NULL,             RESTRICTED_FILE_TEST },
+    { op_file_min,  "s", NULL,             RESTRICTED_FILE_TEST },
+    { op_file_link, "L", NULL,             RESTRICTED_FILE_TEST },
+    { op_file_link, "h", NULL,             RESTRICTED_FILE_TEST },
+    { op_file_xbit, "x", NULL,             RESTRICTED_FILE_TEST },
     { op_file_subr, "F", NULL,             0 },
     { op_url_subr,  "U", NULL,             0 },
     { op_url_subr,  "A", NULL,             0 },
@@ -1776,8 +1786,10 @@ static int core_expr_lookup(ap_expr_lookup_parms *parms)
                 else
                     match = !ap_cstr_casecmp(prov->name, parms->name);
                 if (match) {
-                    if ((parms->flags & AP_EXPR_FLAG_RESTRICTED)
-                        && prov->restricted) {
+                    if (((parms->flags & AP_EXPR_FLAG_RESTRICTED)
+                         && (prov->restricted & RESTRICTED_ALL))
+                        || ((parms->flags & AP_EXPR_FLAG_RESTRICTED_FILE_FUNC)
+                            && (prov->restricted & RESTRICTED_FILE_FUNC))) {
                         *parms->err =
                             apr_psprintf(parms->ptemp,
                                          "%s%s not available in restricted context",