1 # CVE-2013-4505 |
|
2 # http://subversion.apache.org/security/CVE-2013-4505-advisory.txt |
|
3 |
|
4 --- tools/server-side/mod_dontdothat/mod_dontdothat.c 2011-11-28 12:02:41.000000000 -0800 |
|
5 +++ tools/server-side/mod_dontdothat/mod_dontdothat.c 2014-01-29 06:58:46.573510739 -0800 |
|
6 @@ -30,12 +30,14 @@ |
|
7 #include <util_filter.h> |
|
8 #include <ap_config.h> |
|
9 #include <apr_strings.h> |
|
10 +#include <apr_uri.h> |
|
11 |
|
12 #include <expat.h> |
|
13 |
|
14 #include "mod_dav_svn.h" |
|
15 #include "svn_string.h" |
|
16 #include "svn_config.h" |
|
17 +#include "private/svn_fspath.h" |
|
18 |
|
19 module AP_MODULE_DECLARE_DATA dontdothat_module; |
|
20 |
|
21 @@ -161,26 +163,71 @@ |
|
22 } |
|
23 } |
|
24 |
|
25 +/* duplicate of dav_svn__log_err() from mod_dav_svn/util.c */ |
|
26 +static void |
|
27 +log_dav_err(request_rec *r, |
|
28 + dav_error *err, |
|
29 + int level) |
|
30 +{ |
|
31 + dav_error *errscan; |
|
32 + |
|
33 + /* Log the errors */ |
|
34 + /* ### should have a directive to log the first or all */ |
|
35 + for (errscan = err; errscan != NULL; errscan = errscan->prev) { |
|
36 + apr_status_t status; |
|
37 + |
|
38 + if (errscan->desc == NULL) |
|
39 + continue; |
|
40 + |
|
41 +#if AP_MODULE_MAGIC_AT_LEAST(20091119,0) |
|
42 + status = errscan->aprerr; |
|
43 +#else |
|
44 + status = errscan->save_errno; |
|
45 +#endif |
|
46 + |
|
47 + ap_log_rerror(APLOG_MARK, level, status, r, |
|
48 + "%s [%d, #%d]", |
|
49 + errscan->desc, errscan->status, errscan->error_id); |
|
50 + } |
|
51 +} |
|
52 + |
|
53 static svn_boolean_t |
|
54 is_this_legal(dontdothat_filter_ctx *ctx, const char *uri) |
|
55 { |
|
56 const char *relative_path; |
|
57 const char *cleaned_uri; |
|
58 const char *repos_name; |
|
59 + const char *uri_path; |
|
60 int trailing_slash; |
|
61 dav_error *derr; |
|
62 |
|
63 - /* Ok, so we need to skip past the scheme, host, etc. */ |
|
64 - uri = ap_strstr_c(uri, "://"); |
|
65 - if (uri) |
|
66 - uri = ap_strchr_c(uri + 3, '/'); |
|
67 + /* uri can be an absolute uri or just a path, we only want the path to match |
|
68 + * against */ |
|
69 + if (uri && svn_path_is_url(uri)) |
|
70 + { |
|
71 + apr_uri_t parsed_uri; |
|
72 + apr_status_t rv = apr_uri_parse(ctx->r->pool, uri, &parsed_uri); |
|
73 + if (APR_SUCCESS != rv) |
|
74 + { |
|
75 + /* Error parsing the URI, log and reject request. */ |
|
76 + ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, ctx->r, |
|
77 + "mod_dontdothat: blocked request after failing " |
|
78 + "to parse uri: '%s'", uri); |
|
79 + return FALSE; |
|
80 + } |
|
81 + uri_path = parsed_uri.path; |
|
82 + } |
|
83 + else |
|
84 + { |
|
85 + uri_path = uri; |
|
86 + } |
|
87 |
|
88 - if (uri) |
|
89 + if (uri_path) |
|
90 { |
|
91 const char *repos_path; |
|
92 |
|
93 derr = dav_svn_split_uri(ctx->r, |
|
94 - uri, |
|
95 + uri_path, |
|
96 ctx->cfg->base_path, |
|
97 &cleaned_uri, |
|
98 &trailing_slash, |
|
99 @@ -194,7 +241,7 @@ |
|
100 if (! repos_path) |
|
101 repos_path = ""; |
|
102 |
|
103 - repos_path = apr_psprintf(ctx->r->pool, "/%s", repos_path); |
|
104 + repos_path = svn_fspath__canonicalize(repos_path, ctx->r->pool); |
|
105 |
|
106 /* First check the special cases that are always legal... */ |
|
107 for (idx = 0; idx < ctx->allow_recursive_ops->nelts; ++idx) |
|
108 @@ -228,6 +275,18 @@ |
|
109 } |
|
110 } |
|
111 } |
|
112 + else |
|
113 + { |
|
114 + log_dav_err(ctx->r, derr, APLOG_ERR); |
|
115 + return FALSE; |
|
116 + } |
|
117 + } |
|
118 + else |
|
119 + { |
|
120 + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, ctx->r, |
|
121 + "mod_dontdothat: empty uri passed to is_this_legal(), " |
|
122 + "module bug?"); |
|
123 + return FALSE; |
|
124 } |
|
125 |
|
126 return TRUE; |
|
127 |
|