Bug 35077 - mod_dav passes incorrect paths with LocationMatch
Summary: mod_dav passes incorrect paths with LocationMatch
Status: RESOLVED CLOSED
Alias: None
Product: Apache httpd-2
Classification: Unclassified
Component: mod_dav (show other bugs)
Version: 2.2.17
Hardware: PC Linux
: P2 normal with 4 votes (vote)
Target Milestone: ---
Assignee: Apache HTTPD Bugs Mailing List
URL:
Keywords: MassUpdate
Depends on:
Blocks:
 
Reported: 2005-05-26 06:56 UTC by David Anderson
Modified: 2023-10-30 12:54 UTC (History)
2 users (show)



Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description David Anderson 2005-05-26 06:56:41 UTC
when used with a <Location> block, mod_dav extracts the argument to Location and
passes it to inside handlers (namely, mod_dav_svn). This works well for Location
blocks.

However, if a LocationMatch is given with a complex regular expression, the
passed path (the raw regexp) is not practically usable, and causes failures when
handlers expect this path to be valid.

For example, the following configuration causes Subversion to fail in
mod_dav_svn because it doesn't strip the root_path handed down by mod_dav, due
to it being a regular expression instead of the real matched path:

<LocationMatch /svn(?=/[a-z]+)>
  DAV svn
  SvnParentPath /var/lib/svn
</LocationMatch>

mod_dav should do one of two things:
 - retrieve correct path information at runtime, if this is possible (ie.
getting the actual match LocationMatch found, instead of the expression)
 - offer a configuration directive to override this path with a static value.
Comment 1 Paul Querna 2005-06-03 01:07:56 UTC
Is this really a bug in mod_dav, or just mod_dav_svn's handling of it?
Comment 2 David Anderson 2005-06-03 01:53:14 UTC
As far as I can see, mod_dav_svn retrieves a root_dir parameter passed down by
mod_dav, which is the Location root directory. Then it does no extra processing
of this root_dir, and uses it to strip off the irrelevant parts of URIs,
specifically to work out what the repository name is, and what part of the URI
is an intra-repository path.

When the LocationMatch regexp is simple (ie. not actually a regexp at all, just
a plain pattern with no extra regexp markup, like <LocationMatch /svn>),
mod_dav_svn successfully works out the repository name and everything goes well.

However, if the regexp contains regexp markup, mod_dav_svn fails with an error
indicating that it didn't strip the root path off the URIs: trying to open a
repository which has the name of the Location block directory, ie. 'svn' for
/svn/reposname and <LocationMatch /svn(?=/[a-z]+)>. Given the code mod_dav_svn
uses to strip the path, if the root_dir isn't a prefix in the full path, nothing
is stripped at all. The full, raw regexp isn't a prefix in the actual URI, so
nothing gets stripped and mod_dav_svn chokes trying to open the wrong repository
name.

In the case I gave above, if mod_dav_svn had been given the string actually
matched by the regexp, rather than the full raw regexp, it would have resolved
to root_dir being /svn (the lookahead assertion doesn't add text to the match),
and the processing would have gone through as with <LocationMatch /svn>.

That is my rationale for pointing the finger at mod_dav rather than mod_dav_svn:
as mod_dav is the one initially receiving the request through the handler, it
should imho clean up the information it passes to submodules, especially in
cases where there isn't much to gain from passing raw, untreated data.

On the other hand, if it is considered interesting to pass a raw URI to
mod_dav_svn, with the reasoning that it should then process it itself to remove
the excess information (does mod_dav_svn know the request is passed to it
through a LocationMatch? I mean, would it have a way of knowing when to apply
regex logic?), then there is implementation work needed in mod_dav_svn. Off the
top of my head though, I can't think of a good use of passing down regexps to
submodules and leave processing of LocationMatch config to them.

Now, I haven't looked into this much more than working out quickly where the
problem is likely to be by looking through the source code of mod_dav_svn. It
may be a problem with the information apache returns to mod_dav (I don't know
how this is handled in apache yet, so I'm more or less blind here), or maybe it
is mod_dav_svn's task to strip out the excess info mod_dav provides. But
hopefully this extra comment will somewhat explain the reasoning of my reporting
the bug to be with mod_dav.
Comment 3 Kevin Colby 2007-09-19 22:18:53 UTC
This issue perplexed me for quite some time trying to reconfigure our SVN
repositories before I realized the problem was simply the use of actual regex in
LocationMatch.  In spite of this having been reported years ago, it took a lot
of googling before I ran into this bug report.  It seems from reading this and
one other report of the same phenomenon I found
(http://svn.haxx.se/users/archive-2004-07/0653.shtml), also from years ago, that
the nature of the problem is known.  Has this issue just been forgotten, or is
it held up because changing this would cause other problems for other
DAV-related modules or something?  This really seems a problem for SVN setup. 
Without even basic regex markup like ^ and $, I'm not sure it's possible to
allow SVN listing of the repository roots and/or avoid ambiguity in the
LocationMatch patterns for multiple repository stanzas.

Just wondering where this was or if anyone remembered it.  Thanks!
Comment 4 Kevin Richter 2010-07-30 14:41:19 UTC
I have this bug, too.
My config: Apache 2.2.16, Subversion 1.6.12

<LocationMatch "^/">
  DAV svn
  ...
</LocationMatch>

The Apache log says then:
Invalid URI in request PROPFIND %5E/NameOfRepository/!svn/vcc/somefile HTTP/1.1
The %5E is the "^" char in the LocationMatch.

I found a posting with some detailed analysis:
http://www.issociate.de/board/index.php?t=msg&th=141306&rid=0
I hope it helps you to fix the problem.
Comment 5 Andrey Niakhaichyk 2010-10-14 05:44:49 UTC
Confirm

<LocationMatch "^/(?!external)">
  DAV svn
  SVNParentPath /data/subversion
</LocationMatch>

<Location /external/ad>
  DAV svn
  SVNPath /data/subversion/ad
  AuthType Basic
  ...
</Location>

Result:
In some cases we see the regexp symbols in log.
192.168.9.127 - - [14/Oct/2010:09:24:57 +0000] "OPTIONS /ad HTTP/1.1" 200 204 "-" "SVN/1.6.13 (r1002816) neon/0.29.3"
192.168.9.127 - - [14/Oct/2010:09:24:57 +0000] "PROPFIND /ad HTTP/1.1" 207 661 "-" "SVN/1.6.13 (r1002816) neon/0.29.3"
192.168.9.127 - - [14/Oct/2010:09:24:57 +0000] "PROPFIND %5E/(%3F!external)/ad/!svn/vcc/default HTTP/1.1" 400 298 "-" "SVN/1.6.13 (r1002816) neon/0.29.3"
Comment 6 Timur I. Bakeyev 2010-12-24 11:22:53 UTC
Still the same problem with mod_dav, mod_dav_svn and LocationMatch.

<LocationMatch ^/(?:cliq|ops)/>
        DAV svn
        SVNParentPath /opt/svn
        SVNPathAuthz On
        ....
</LocationMatch>

This setup works with browsing of the SVN repositories via HTTP browser, but fails 
with the mentioned above errors about PROPFIND when trying to use Eclipse or any other client, that requires properties from the SVN repository.

Please, fix it! Shouldn't be so hard for 5 y.o. bug :)
Comment 7 Stefan Fritsch 2010-12-28 08:04:30 UTC
Trying to guess where the repository part should start will lead to ambiguities with more complex regular expression. I think the only general solution is to add a DAVBaseURL directive which allows the user to specify what he actually meant.
Comment 8 Timur I. Bakeyev 2010-12-28 10:19:23 UTC
(In reply to comment #7)
> Trying to guess where the repository part should start will lead to ambiguities
> with more complex regular expression. I think the only general solution is to
> add a DAVBaseURL directive which allows the user to specify what he actually
> meant.

I don't see, how it is related. There is nothing to do with the repository path in that particular case. We have a combination of LocationMatch, mod_dav and mod_dav_svn.

The first one is responsible to match the location, which was requested from the server with the given configuration block. And the result of it is binary - either 'yes' or 'no'. and if it is 'yes' - we have very exact path(local part of the URI) that did match it! If it matched something, that wasn't aimed to - well, blame the writer of the regex.

But, in any case, as soon as the block matched - we should have exact URI which should be passed to the mod_dav instead of cryptic regular expression. I'm not sure how easy is to implement it, but at least, that what I'd expect, comparing with the behavior in case of Location.

There is absolutely nothing that makes this situation specific to the mod_dav_svn. It just consumes what mod_dav passed to it, and in this situation mod_dav passes garbage.
Comment 9 Stefan Fritsch 2010-12-28 12:18:22 UTC
(In reply to comment #8)
> The first one is responsible to match the location, which was requested from
> the server with the given configuration block. And the result of it is binary -
> either 'yes' or 'no'. and if it is 'yes' - we have very exact path(local part
> of the URI) that did match it! If it matched something, that wasn't aimed to -
> well, blame the writer of the regex.

Well, given a few posibilities, like

^/svn/(?:projecta|projectb)/
^/svn/(?=projecta|projectb)/
^/svn/(?=projecta/|projectb/)

I doubt that many people know pcre well enough to know that they need the third option. And there are other containers which would confuse mod_dav even more, like <FilesMatch> and <If> (in 2.3/2.4).

Another problem is that result of the regex match is not available to mod_dav. Mod_dav would probably have to re-do the regexp match to find out which part matched.

> There is absolutely nothing that makes this situation specific to the
> mod_dav_svn.

That is true.
Comment 10 William A. Rowe Jr. 2018-11-07 21:09:03 UTC
Please help us to refine our list of open and current defects; this is a mass update of old and inactive Bugzilla reports which reflect user error, already resolved defects, and still-existing defects in httpd.

As repeatedly announced, the Apache HTTP Server Project has discontinued all development and patch review of the 2.2.x series of releases. The final release 2.2.34 was published in July 2017, and no further evaluation of bug reports or security risks will be considered or published for 2.2.x releases. All reports older than 2.4.x have been updated to status RESOLVED/LATER; no further action is expected unless the report still applies to a current version of httpd.

If your report represented a question or confusion about how to use an httpd feature, an unexpected server behavior, problems building or installing httpd, or working with an external component (a third party module, browser etc.) we ask you to start by bringing your question to the User Support and Discussion mailing list, see [https://httpd.apache.org/lists.html#http-users] for details. Include a link to this Bugzilla report for completeness with your question.

If your report was clearly a defect in httpd or a feature request, we ask that you retest using a modern httpd release (2.4.33 or later) released in the past year. If it can be reproduced, please reopen this bug and change the Version field above to the httpd version you have reconfirmed with.

Your help in identifying defects or enhancements still applicable to the current httpd server software release is greatly appreciated.
Comment 11 Joe Orton 2023-08-14 12:27:29 UTC
I'm working on a patch for this exactly as Stefan suggests above, adding a "DavBasePath" directive which is then used as the root path of the repo.

https://github.com/apache/httpd/pull/376

In my testing this fixes the mod_dav_svn case.
Comment 12 Joe Orton 2023-08-14 14:41:22 UTC
Now fixed on trunk via r1911651
Comment 13 Joe Orton 2023-10-30 12:54:14 UTC
Merged in 2.4.58 - see r1912081