Change to Module DB
User ID : 1485 Title: mod_vlimitconn Details : https://modules.apache.org/search.php?id=2558
Re: With IP address in Host: header ServerName/ServerAlias doesn't work
Hi, On 08/22/2011 07:05 PM CEST +02:00, Eric Covener wrote: Do you agree that this is something that needs to be fixed? If yes I could start to work on a patch... I was skeptical but it certainly looks busted for non-wildcard NVH'es (that can match the strcmp with the VH addr) like you've explained. I suggest opening a bugzilla ticket to track. I've just opened ticket #51709. https://issues.apache.org/bugzilla/show_bug.cgi?id=51709 Please find attached my patch for check_hostalias(). I tried to stick to the idea to do the ServerName and ServerAlias check only once for each server. Also for this reason the result is in the end merely a rewrite of this function. I hope though that it is clear enough how it is intended to work. However, I believe the fix is yet incomplete. The function ap_matches_request_vhost() used by modules like mod_proxy seems to implement the virtual host check also in the wrong order. From reading the comments within that function, apparently someone else wondered about my issue in the past too: /* search all the VirtualHost values */ /* XXX: If this is a NameVirtualHost then we may not be doing the * Right Thing. consider: * * NameVirtualHost 10.1.1.1 * VirtualHost 10.1.1.1 * ServerName v1 * /VirtualHost * VirtualHost 10.1.1.1 * ServerName v2 * /VirtualHost * * Suppose r-server is v2, and we're asked to match 10.1.1.1. * We'll say yup it's v2, when really it isn't... * if a request came in for 10.1.1.1 it would really go to v1. */ I'll follow up with a patch for this function later. Regards, Micha diff -ur httpd-2.2.19.orig//server/vhost.c httpd-2.2.19.patched//server/vhost.c --- httpd-2.2.19.orig//server/vhost.c 2010-08-10 21:11:40.0 +0200 +++ httpd-2.2.19.patched//server/vhost.c 2011-08-23 10:31:49.827506728 +0200 @@ -872,9 +872,11 @@ const char *host = r-hostname; apr_port_t port; server_rec *s; +server_rec *virthost_s; server_rec *last_s; name_chain *src; +virthost_s = NULL; last_s = NULL; port = r-connection-local_addr-port; @@ -901,23 +903,34 @@ s = src-server; -/* does it match the virthost from the sar? */ -if (!strcasecmp(host, sar-virthost)) { -goto found; -} - -if (s == last_s) { -/* we've already done ServerName and ServerAlias checks for this - * vhost - */ -continue; +/* If we still need to do ServerName and ServerAlias checks for this + * server, do them now. + */ +if (s != last_s) { +/* does it match any ServerName or ServerAlias directive? */ +if (matches_aliases(s, host)) { +goto found; +} } last_s = s; -if (matches_aliases(s, host)) { -goto found; +/* Fallback: does it match the virthost from the sar? */ +if (!strcasecmp(host, sar-virthost)) { +/* only the first match is used */ +if (virthost_s == NULL) { +virthost_s = s; +} } } + +/* If ServerName and ServerAlias check failed, we end up here. If it + * matches a VirtualHost, virthost_s is set. Use that as fallback + */ +if (virthost_s) { +s = virthost_s; +goto found; +} + return; found:
Re: With IP address in Host: header ServerName/ServerAlias doesn't work
Hi, On 08/23/2011 10:42 AM CEST +02:00, Micha Lenk wrote: However, I believe the fix is yet incomplete. The function ap_matches_request_vhost() used by modules like mod_proxy seems to implement the virtual host check also in the wrong order. [...] I'll follow up with a patch for this function later. Here you go. Attached is the suggested patch for the function ap_matches_request_vhost(). Anything else missing? Regards, Micha diff -u4 -r httpd-2.2.19.orig//server/vhost.c httpd-2.2.19.patched//server/vhost.c --- httpd-2.2.19.orig//server/vhost.c 2010-08-10 21:11:40.0 +0200 +++ httpd-2.2.19.patched//server/vhost.c 2011-08-23 12:01:04.247092813 +0200 @@ -820,38 +820,22 @@ server_addr_rec *sar; s = r-server; -/* search all the VirtualHost values */ -/* XXX: If this is a NameVirtualHost then we may not be doing the Right Thing - * consider: - * - * NameVirtualHost 10.1.1.1 - * VirtualHost 10.1.1.1 - * ServerName v1 - * /VirtualHost - * VirtualHost 10.1.1.1 - * ServerName v2 - * /VirtualHost - * - * Suppose r-server is v2, and we're asked to match 10.1.1.1. We'll say - * yup it's v2, when really it isn't... if a request came in for 10.1.1.1 - * it would really go to v1. - */ +/* search the ServerName and all the ServerAlias values */ +if ((port == s-port) matches_aliases(s, host)) { +return 1; +} + +/* Fallback: search all the VirtualHost values */ for (sar = s-addrs; sar; sar = sar-next) { if ((sar-host_port == 0 || port == sar-host_port) !strcasecmp(host, sar-virthost)) { return 1; } } -/* the Port has to match now, because the rest don't have ports associated - * with them. */ -if (port != s-port) { -return 0; -} - -return matches_aliases(s, host); +return 0; } static void check_hostalias(request_rec *r)
RE: With IP address in Host: header ServerName/ServerAlias doesn't work
-Original Message- From: Micha Lenk [mailto:mi...@lenk.info] Sent: Dienstag, 23. August 2011 12:08 To: dev@httpd.apache.org Subject: Re: With IP address in Host: header ServerName/ServerAlias doesn't work Hi, On 08/23/2011 10:42 AM CEST +02:00, Micha Lenk wrote: However, I believe the fix is yet incomplete. The function ap_matches_request_vhost() used by modules like mod_proxy seems to implement the virtual host check also in the wrong order. [...] I'll follow up with a patch for this function later. Here you go. Attached is the suggested patch for the function ap_matches_request_vhost(). Anything else missing? IMHO the patch does not solve the issue mentioned in the comment and is not needed. Keep in mind the difference between ap_matches_request_vhost and check_host_alias: ap_matches_request_vhost checks only the data of *one* server_rec and hence only *one* Servername and ServerAlias settings as set for this vhost, whereas check_host_alias scans over *multiple* server_recs with *multiple* Servername and ServerAlias settings from different vhosts. Regards Rüdiger
DoS with mod_deflate range requests
http://seclists.org/fulldisclosure/2011/Aug/175 I haven't looked into it so far. And I am not sure I will have time today.
RE: DoS with mod_deflate range requests
-Original Message- From: Stefan Fritsch [mailto:s...@sfritsch.de] Sent: Dienstag, 23. August 2011 13:09 To: dev@httpd.apache.org Subject: DoS with mod_deflate range requests http://seclists.org/fulldisclosure/2011/Aug/175 I haven't looked into it so far. And I am not sure I will have time today. After checking the attack script and the code this has IMHO nothing to do with mod_deflate but only with the byterange filter. But I admit that haven't run the script to check. The host is seen as vulnerable if it replies to a range request that requests the whole entity via a range 0- with a partial response. A possible problem is that the output bucket brigade gets transformed in a one bucket per byte brigade and thus into a brigade with many buckets. Futhermore the created range response has a lot of buckets with boundaries, strings allocated from r-pool. So it might be advisable if we limit the number of ranges we accept contained in a Range header. As a further optimization we could check for 0- ranges and once we hit one just reply with the full response instead of a partial response. Regards Rüdiger
Re: DoS with mod_deflate range requests
2011/8/23 Stefan Fritsch s...@sfritsch.de: http://seclists.org/fulldisclosure/2011/Aug/175 I haven't looked into it so far. And I am not sure I will have time today. it is sending HEAD requests with lots of ranges HEAD / HTTP/1.1 Host: Range:bytes=0-,5-1,5-2,5-3,. the code in ap_byterange_filter() http://svn.apache.org/repos/asf/httpd/httpd/branches/2.2.x/modules/http/byterange_filter.c creates a bucket for every range element, the number of buckets is limited by the size of the document in published code but I think it can be enchanced by using 1-2,1-3,..1-doc_size,2-1,2-2, 2-doc_size doeas Range in HEAD request have any sense at all ?
Re: DoS with mod_deflate range requests
On Tue, Aug 23, 2011 at 02:15:16PM +0200, Lazy wrote: 2011/8/23 Stefan Fritsch s...@sfritsch.de: http://seclists.org/fulldisclosure/2011/Aug/175 I haven't looked into it so far. And I am not sure I will have time today. it is sending HEAD requests with lots of ranges HEAD / HTTP/1.1 Host: Range:bytes=0-,5-1,5-2,5-3,. … doeas Range in HEAD request have any sense at all ? One /possible/ use is as an equivalent for a conditional GET, ie GET / HTTP/1.1 Host: xxx Range: bytes=1024- If-Range: foo …to which the correct response should I think be either 200 or 206 depending on whether the document is modified. But it's a pretty odd case. I can't imagine any published client or proxy that would make such a request. It would in any case be acceptable to return a 200 response instead; RFC 2616 states that A server MAY ignore the Range header Tim Bannister
memcached lookups in apache module
Hi, I'm working on an apache module that basically rewrites URLs based on a simple memcached lookup. I've noticed that apr-util already comes with memcached functions but I'm wondering about the apr_memcache_server_create() argument semantics. Apparently I have to provide minimum, soft maximum, hard maximum and a time-to-live value and I'm not sure what values are sensible here. I'm dealing with ten webservers accessing ten memcached servers and there are going to be lookups between all systems all the time so I really don't need any dynamic behavior. What are good values for the minimum number of connections? 1, 10, 100? The hard maximum number is obvious but what is the purpose of the soft maximum number of connections? Thanks, Dennis
Re: memcached lookups in apache module
On Tue, 23 Aug 2011 16:11:59 +0200 Dennis Jacobfeuerborn denni...@conversis.de wrote: Hi, I'm working on an apache module that basically rewrites URLs based on a simple memcached lookup. I've noticed that apr-util already comes with memcached functions but I'm wondering about the apr_memcache_server_create() argument semantics. Look in trunk or 2.3.x instead of 2.2, and you have the readymade socache modules, including one which provides memcache. BTW, this would be more on-topic for the modules-dev list. -- Nick Kew
Re: memcached lookups in apache module
On 08/23/2011 04:35 PM, Nick Kew wrote: On Tue, 23 Aug 2011 16:11:59 +0200 Dennis Jacobfeuerborndenni...@conversis.de wrote: Hi, I'm working on an apache module that basically rewrites URLs based on a simple memcached lookup. I've noticed that apr-util already comes with memcached functions but I'm wondering about the apr_memcache_server_create() argument semantics. Look in trunk or 2.3.x instead of 2.2, and you have the readymade socache modules, including one which provides memcache. Thanks. I've taken a quick look at mod_socache_memcache and mod_authn_socache and I think I've got an idea how to implement this. What is the status of 2.3/2.4? Is the current code semi production ready and do you know when 2.4 will be released? Regards, Dennis
Re: DoS with mod_deflate range requests
On 8/23/2011 6:08 AM, Stefan Fritsch wrote: http://seclists.org/fulldisclosure/2011/Aug/175 I haven't looked into it so far. And I am not sure I will have time today. Until range can be completely addressed, avoiding excessive numbers of ranges (tricky) or overlapping ranges (pretty straightforward)... what about simply disabling deflate on range requests?
Re: DoS with mod_deflate range requests
On Tuesday 23 August 2011, William A. Rowe Jr. wrote: On 8/23/2011 6:08 AM, Stefan Fritsch wrote: http://seclists.org/fulldisclosure/2011/Aug/175 I haven't looked into it so far. And I am not sure I will have time today. Until range can be completely addressed, avoiding excessive numbers of ranges (tricky) or overlapping ranges (pretty straightforward)... what about simply disabling deflate on range requests? There is this PR: https://issues.apache.org/bugzilla/show_bug.cgi?id=49772 mod_deflate kicks itself out on Content-Range responses but not on multipart/byteranges This may be one of the issues. But as Rüdiger pointed out, there is also an issue without mod_deflate. From looking at the code, I think the problem is the bucket structs. With N the number of requested ranges, the initial brigade is partitioned into 2*N buckets at the maximum. Then those buckets are copied into the output brigade N times, which means that O(N^2) buckets are created. The data is not copied, and only N A-B strings are allocated from the pool. But the sum of those is limited by LimitRequestFieldSize, so it shouldn't be a problem. Maybe the byte-range filter should call ap_pass_brigade every 10 ranges or so? Then the buckets should be freed earlier (at least if all filters down the chain behave correctly).
Re: DoS with mod_deflate range requests
please tell me how to unsubscribe from this mailing list On Tue, Aug 23, 2011 at 9:49 PM, Stefan Fritsch s...@sfritsch.de wrote: On Tuesday 23 August 2011, William A. Rowe Jr. wrote: On 8/23/2011 6:08 AM, Stefan Fritsch wrote: http://seclists.org/fulldisclosure/2011/Aug/175 I haven't looked into it so far. And I am not sure I will have time today. Until range can be completely addressed, avoiding excessive numbers of ranges (tricky) or overlapping ranges (pretty straightforward)... what about simply disabling deflate on range requests? There is this PR: https://issues.apache.org/bugzilla/show_bug.cgi?id=49772 mod_deflate kicks itself out on Content-Range responses but not on multipart/byteranges This may be one of the issues. But as Rüdiger pointed out, there is also an issue without mod_deflate. From looking at the code, I think the problem is the bucket structs. With N the number of requested ranges, the initial brigade is partitioned into 2*N buckets at the maximum. Then those buckets are copied into the output brigade N times, which means that O(N^2) buckets are created. The data is not copied, and only N A-B strings are allocated from the pool. But the sum of those is limited by LimitRequestFieldSize, so it shouldn't be a problem. Maybe the byte-range filter should call ap_pass_brigade every 10 ranges or so? Then the buckets should be freed earlier (at least if all filters down the chain behave correctly). -- Mohamed D. Sulaiman Farmer's Commercial Bank Banking Technology Unit Cell: (+249) 923407600 Website: http://www.mohameddawaina.site40.net
Re: DoS with mod_deflate range requests
On 8/23/2011 1:49 PM, Stefan Fritsch wrote: From looking at the code, I think the problem is the bucket structs. With N the number of requested ranges, the initial brigade is partitioned into 2*N buckets at the maximum. Then those buckets are copied into the output brigade N times, which means that O(N^2) buckets are created. The data is not copied, and only N A-B strings are allocated from the pool. But the sum of those is limited by LimitRequestFieldSize, so it shouldn't be a problem. Maybe the byte-range filter should call ap_pass_brigade every 10 ranges or so? Then the buckets should be freed earlier (at least if all filters down the chain behave correctly). I suggest we should be parsing and reassembling the list before we start the bucket logic. I'd also suggest the following... This example from the spec... - Several legal but not canonical specifications of the second 500 bytes (byte offsets 500-999, inclusive): bytes=500-600,601-999 bytes=500-700,601-999 does not say the last is 200 bytes and 400 bytes, but is explicitly the second 500 bytes. I propose we satisfy range requests in the only sensible manner, returning the ranges in sequence, using a linked list of buckets and combining all ranges or another mechanism to work out the applicable ranges. The range processing is limited to some 4000 parts (consisting entirely of invalid -, segments), and as a practical matter much less than 2500. Reassemble the list of ranges in sequence as a pre-parsing step, and we can much more efficiently generate the response with no duplication. The spec is ambiguous but nowhere suggested that duplicate ranges would be legitimate.
Re: DoS with mod_deflate range requests
On Tue, Aug 23, 2011 at 3:32 PM, William A. Rowe Jr. wr...@rowe-clan.netwrote: I suggest we should be parsing and reassembling the list before we start the bucket logic. I propose we satisfy range requests in the only sensible manner, returning the ranges in sequence, yeah, overlapping ranges should be merged up front. That ought to completely fix the issue. fwiw, I played with the script to create the attack and noticed this: Content-Length: 950883 That's probably the sum of the overlapping ranges. My original file is 3929 bytes long. Greg
Re: DoS with mod_deflate range requests
On 8/23/2011 4:00 PM, Greg Ames wrote: On Tue, Aug 23, 2011 at 3:32 PM, William A. Rowe Jr. wrote: I suggest we should be parsing and reassembling the list before we start the bucket logic. I propose we satisfy range requests in the only sensible manner, returning the ranges in sequence, yeah, overlapping ranges should be merged up front. That ought to completely fix the issue. So the only remaining question; are we free to reorder them into sequence? Even in the most pedantic case, I believe that the total array shouldn't ever exceed 1024, because in those cases a large number of the acceptable expected ranges should be in the nnn-nnn, format, or 8 characters long, out of our MAX_LINE_LENGTH of some 8190. If we argue that asking for single bytes is simply wrong, we should probably allocate some 16 ranges and grow the list by a power of four, resulting in a max of some 4 allocs and maximum memory consumption of less than 64k per request.
Re: DoS with mod_deflate range requests
Am 23.08.2011 20:52, schrieb Mohamed Dawaina: please tell me how to unsubscribe from this mailing list what about looking in the mail-header or login with your acount you have registered? Precedence: bulk Reply-To: dev@httpd.apache.org list-help: mailto:dev-h...@httpd.apache.org list-unsubscribe: mailto:dev-unsubscr...@httpd.apache.org List-Post: mailto:dev@httpd.apache.org List-Id: dev.httpd.apache.org signature.asc Description: OpenPGP digital signature
Re: DoS with mod_deflate range requests
On Tuesday 23 August 2011, William A. Rowe Jr. wrote: On 8/23/2011 4:00 PM, Greg Ames wrote: On Tue, Aug 23, 2011 at 3:32 PM, William A. Rowe Jr. wrote: I suggest we should be parsing and reassembling the list before we start the bucket logic. I propose we satisfy range requests in the only sensible manner, returning the ranges in sequence, yeah, overlapping ranges should be merged up front. That ought to completely fix the issue. So the only remaining question; are we free to reorder them into sequence? Good point. I haven't seen anything in the RFC about that. I guess that there are at least some clients that will be broken by that. Nevertheless, I have done a first try at a patch. The necessary modification to only merge and not reorder should be small. I have done only limited testing, so there are probably some bugs. There are no tests with multiple ranges in the test-framework, yet. Even in the most pedantic case, I believe that the total array shouldn't ever exceed 1024, because in those cases a large number of the acceptable expected ranges should be in the nnn-nnn, format, or 8 characters long, out of our MAX_LINE_LENGTH of some 8190. If we argue that asking for single bytes is simply wrong, we should probably allocate some 16 ranges and grow the list by a power of four, resulting in a max of some 4 allocs and maximum memory consumption of less than 64k per request. Just counting the commas in the header line seems acceptable to me. In any case, single byte ranges are explicitly mentioned in the RFC as example, so we probably should not disallow those. diff --git a/modules/http/byterange_filter.c b/modules/http/byterange_filter.c index 13bf0a1..6a40420 100644 --- a/modules/http/byterange_filter.c +++ b/modules/http/byterange_filter.c @@ -61,6 +61,11 @@ APLOG_USE_MODULE(http); +/* returns + * 0 if range invalid or whole file + * +1 for valid range spec + * -1 for start end + */ static int parse_byterange(char *range, apr_off_t clength, apr_off_t *start, apr_off_t *end) { @@ -114,13 +119,6 @@ static int parse_byterange(char *range, apr_off_t clength, static int ap_set_byterange(request_rec *r); -typedef struct byterange_ctx { -apr_bucket_brigade *bb; -int num_ranges; -char *boundary; -char *bound_head; -} byterange_ctx; - /* * Here we try to be compatible with clients that want multipart/x-byteranges * instead of multipart/byteranges (also see above), as per HTTP/1.1. We @@ -136,26 +134,43 @@ static int use_range_x(request_rec *r) ap_strstr_c(ua, MSIE 3))); } +struct range_spec { +apr_off_t start, end; +}; + +static int sort_fn(const void *a_, const void *b_) +{ +const struct range_spec *a = a_, *b = b_; +if (a-start b-start) +return -1; +else if (a-start == b-start) +return 0; +else +return 1; +} + #define BYTERANGE_FMT % APR_OFF_T_FMT -% APR_OFF_T_FMT /% APR_OFF_T_FMT #define PARTITION_ERR_FMT apr_brigade_partition() failed \ [% APR_OFF_T_FMT ,% APR_OFF_T_FMT ] +#define MAX(o1, o2) ((o1 o2) ? o1 : o2) AP_CORE_DECLARE_NONSTD(apr_status_t) ap_byterange_filter(ap_filter_t *f, apr_bucket_brigade *bb) { -#define MIN_LENGTH(len1, len2) ((len1 len2) ? len2 : len1) request_rec *r = f-r; conn_rec *c = r-connection; -byterange_ctx *ctx; apr_bucket *e; apr_bucket_brigade *bsend; -apr_off_t range_start; -apr_off_t range_end; +apr_off_t max = 0; char *current; apr_off_t clength = 0; apr_status_t rv; -int found = 0; +int found = 0, i = 0; +int need_sort = 0; int num_ranges; +char *boundary = NULL; +char *bound_head = NULL; +struct range_spec *ranges; /* Iterate through the brigade until reaching EOS or a bucket with * unknown length. */ @@ -183,64 +198,78 @@ AP_CORE_DECLARE_NONSTD(apr_status_t) ap_byterange_filter(ap_filter_t *f, return ap_pass_brigade(f-next, bb); } -ctx = apr_pcalloc(r-pool, sizeof(*ctx)); -ctx-num_ranges = num_ranges; -/* create a brigade in case we never call ap_save_brigade() */ -ctx-bb = apr_brigade_create(r-pool, c-bucket_alloc); - -if (ctx-num_ranges 1) { +if (num_ranges 1) { /* Is ap_make_content_type required here? */ const char *orig_ct = ap_make_content_type(r, r-content_type); -ctx-boundary = apr_psprintf(r-pool, % APR_UINT64_T_HEX_FMT %lx, - (apr_uint64_t)r-request_time, (long) getpid()); +boundary = apr_psprintf(r-pool, % APR_UINT64_T_HEX_FMT %lx, +(apr_uint64_t)r-request_time, (long) getpid()); ap_set_content_type(r, apr_pstrcat(r-pool, multipart, use_range_x(r) ? /x- : /,
Re: DoS with mod_deflate range requests
On Aug 23, 2011, at 2:34 PM, William A. Rowe Jr. wrote: On 8/23/2011 4:00 PM, Greg Ames wrote: On Tue, Aug 23, 2011 at 3:32 PM, William A. Rowe Jr. wrote: I suggest we should be parsing and reassembling the list before we start the bucket logic. I propose we satisfy range requests in the only sensible manner, returning the ranges in sequence, yeah, overlapping ranges should be merged up front. That ought to completely fix the issue. So the only remaining question; are we free to reorder them into sequence? And the spec says ... When a client requests multiple ranges in one request, the server SHOULD return them in the order that they appeared in the request. My suggestion is to reject any request with overlapping ranges or more than five ranges with a 416, and to send 200 for any request with 4-5 ranges. There is simply no need to support random access in HTTP. Roy