summaryrefslogtreecommitdiffstats
path: root/debian/patches/0056-CVE-2023-25690-Regression-2.patch
blob: 55eaa6b41dbfc29c22ef4c15ece94421ee576632 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
From 07b802c934b841d376733a3e2ecfa55f6b0ee994 Mon Sep 17 00:00:00 2001
From: Eric Covener <covener@apache.org>
Date: Sat, 11 Mar 2023 20:57:52 +0000
Subject: [PATCH] allow decoded chars when they will be escaped

git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1908296 13f79535-47bb-0310-9956-ffa450edef68
---
 changes-entries/rewrite-escape.diff |  3 ++
 modules/mappers/mod_rewrite.c       | 45 +++++++++++++++++------------
 2 files changed, 30 insertions(+), 18 deletions(-)
 create mode 100644 changes-entries/rewrite-escape.diff

Index: apache2/changes-entries/rewrite-escape.diff
===================================================================
--- /dev/null
+++ apache2/changes-entries/rewrite-escape.diff
@@ -0,0 +1,3 @@
+  *) mod_rewrite: Re-allow some proxy and redirect substitutions flagged as
+     403 errors in 2.4.56. [Eric Covener]
+
Index: apache2/modules/mappers/mod_rewrite.c
===================================================================
--- apache2.orig/modules/mappers/mod_rewrite.c
+++ apache2/modules/mappers/mod_rewrite.c
@@ -4705,14 +4705,19 @@ static int hook_uri2file(request_rec *r)
     }
 
     if (rulestatus) {
-        unsigned skip;
-        apr_size_t flen;
-        int to_proxyreq;
-
-        if (r->args && *(ap_scan_vchar_obstext(r->args))) {
+        unsigned skip_absolute = is_absolute_uri(r->filename, NULL);
+        apr_size_t flen =  r->filename ? strlen(r->filename) : 0;
+        int to_proxyreq = (flen > 6 && strncmp(r->filename, "proxy:", 6) == 0);
+        int will_escape = (to_proxyreq || skip_absolute)
+            && (rulestatus != ACTION_NOESCAPE);
+
+        if (r->args
+                && !will_escape
+                && *(ap_scan_vchar_obstext(r->args))) {
             /*
              * We have a raw control character or a ' ' in r->args.
-             * Correct encoding was missed.
+             * Correct encoding was missed and we're not going to escape
+             * it before returning.
              */
             ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(10410)
                           "Rewritten query string contains control "
@@ -4727,9 +4732,6 @@ static int hook_uri2file(request_rec *r)
             return n;
         }
 
-        flen = r->filename ? strlen(r->filename) : 0;
-        to_proxyreq = (flen > 6 && strncmp(r->filename, "proxy:", 6) == 0);
-
         /* If a pre_trans reverse "proxy:" filename gets rewritten to
          * a non-proxy one this is not a proxy request anymore.
          */
@@ -4782,15 +4784,15 @@ static int hook_uri2file(request_rec *r)
                         r->filename));
             return OK;
         }
-        else if ((skip = is_absolute_uri(r->filename, NULL)) > 0) {
+        else if (skip_absolute > 0) {
             int n;
 
             /* it was finally rewritten to a remote URL */
 
             if (rulestatus != ACTION_NOESCAPE) {
                 rewritelog((r, 1, NULL, "escaping %s for redirect",
-                            r->filename));
-                r->filename = escape_absolute_uri(r->pool, r->filename, skip);
+                           r->filename));
+                r->filename = escape_absolute_uri(r->pool, r->filename, skip_absolute);
             }
 
             /* append the QUERY_STRING part */
@@ -5016,9 +5018,17 @@ static int hook_fixup(request_rec *r)
      */
     rulestatus = apply_rewrite_list(r, dconf->rewriterules, dconf->directory);
     if (rulestatus) {
-        unsigned skip;
+        unsigned skip_absolute = is_absolute_uri(r->filename, NULL);
+        int to_proxyreq = 0;
+        int will_escape = 0;
 
-        if (r->args && *(ap_scan_vchar_obstext(r->args))) {
+        l = strlen(r->filename);
+        to_proxyreq = l > 6 && strncmp(r->filename, "proxy:", 6) == 0;
+        will_escape = skip_absolute && (rulestatus != ACTION_NOESCAPE);
+
+        if (r->args
+               && !will_escape
+               &&  *(ap_scan_vchar_obstext(r->args))) {
             /*
              * We have a raw control character or a ' ' in r->args.
              * Correct encoding was missed.
@@ -5036,8 +5046,7 @@ static int hook_fixup(request_rec *r)
             return n;
         }
 
-        l = strlen(r->filename);
-        if (l > 6 && strncmp(r->filename, "proxy:", 6) == 0) {
+        if (to_proxyreq) {
             /* it should go on as an internal proxy request */
 
             /* make sure the QUERY_STRING and
@@ -5061,7 +5070,7 @@ static int hook_fixup(request_rec *r)
                         "%s [OK]", r->filename));
             return OK;
         }
-        else if ((skip = is_absolute_uri(r->filename, NULL)) > 0) {
+        else if (skip_absolute > 0) {
             /* it was finally rewritten to a remote URL */
 
             /* because we are in a per-dir context
@@ -5070,7 +5079,7 @@ static int hook_fixup(request_rec *r)
              */
             if (dconf->baseurl != NULL) {
                 /* skip 'scheme://' */
-                cp = r->filename + skip;
+                cp = r->filename + skip_absolute;
 
                 if ((cp = ap_strchr(cp, '/')) != NULL && *(++cp)) {
                     rewritelog((r, 2, dconf->directory,
@@ -5114,8 +5123,8 @@ static int hook_fixup(request_rec *r)
             /* now prepare the redirect... */
             if (rulestatus != ACTION_NOESCAPE) {
                 rewritelog((r, 1, dconf->directory, "escaping %s for redirect",
-                            r->filename));
-                r->filename = escape_absolute_uri(r->pool, r->filename, skip);
+                           r->filename));
+                r->filename = escape_absolute_uri(r->pool, r->filename, skip_absolute);
             }
 
             /* append the QUERY_STRING part */