mirror of
https://github.com/caddyserver/caddy.git
synced 2025-01-13 22:51:08 -05:00
http: Patch path matcher to ignore dots and spaces (#2917)
(Try saying "patch path match" ten times fast)
This commit is contained in:
parent
6455efa5d3
commit
dae4913fe3
4 changed files with 23 additions and 2 deletions
|
@ -165,6 +165,14 @@ func (m MatchPath) Provision(_ caddy.Context) error {
|
||||||
// Match returns true if r matches m.
|
// Match returns true if r matches m.
|
||||||
func (m MatchPath) Match(r *http.Request) bool {
|
func (m MatchPath) Match(r *http.Request) bool {
|
||||||
lowerPath := strings.ToLower(r.URL.Path)
|
lowerPath := strings.ToLower(r.URL.Path)
|
||||||
|
|
||||||
|
// see #2917; Windows ignores trailing dots and spaces
|
||||||
|
// when accessing files (sigh), potentially causing a
|
||||||
|
// security risk (cry) if PHP files end up being served
|
||||||
|
// as static files, exposing the source code, instead of
|
||||||
|
// being matched by *.php to be treated as PHP scripts
|
||||||
|
lowerPath = strings.TrimRight(lowerPath, ". ")
|
||||||
|
|
||||||
for _, matchPath := range m {
|
for _, matchPath := range m {
|
||||||
// special case: first character is equals sign,
|
// special case: first character is equals sign,
|
||||||
// treat it as an exact match
|
// treat it as an exact match
|
||||||
|
|
|
@ -247,6 +247,18 @@ func TestPathMatcher(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestPathMatcherWindows(t *testing.T) {
|
||||||
|
// only Windows has this bug where it will ignore
|
||||||
|
// trailing dots and spaces in a filename, but we
|
||||||
|
// test for it on all platforms to be more consistent
|
||||||
|
match := MatchPath{"*.php"}
|
||||||
|
req := &http.Request{URL: &url.URL{Path: "/index.php . . .."}}
|
||||||
|
matched := match.Match(req)
|
||||||
|
if !matched {
|
||||||
|
t.Errorf("Expected to match; should ignore trailing dots and spaces")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestPathREMatcher(t *testing.T) {
|
func TestPathREMatcher(t *testing.T) {
|
||||||
for i, tc := range []struct {
|
for i, tc := range []struct {
|
||||||
match MatchPathRE
|
match MatchPathRE
|
||||||
|
|
|
@ -115,7 +115,8 @@ func (t *Transport) UnmarshalCaddyfile(d *caddyfile.Dispenser) error {
|
||||||
// php_fastcgi /subpath localhost:7777
|
// php_fastcgi /subpath localhost:7777
|
||||||
//
|
//
|
||||||
// then the resulting routes are wrapped in a subroute that uses the
|
// then the resulting routes are wrapped in a subroute that uses the
|
||||||
// user's matcher as a prerequisite to enter the subroute.
|
// user's matcher as a prerequisite to enter the subroute. In other
|
||||||
|
// words, the directive's matcher is necessary, but not sufficient.
|
||||||
func parsePHPFastCGI(h httpcaddyfile.Helper) ([]httpcaddyfile.ConfigValue, error) {
|
func parsePHPFastCGI(h httpcaddyfile.Helper) ([]httpcaddyfile.ConfigValue, error) {
|
||||||
if !h.Next() {
|
if !h.Next() {
|
||||||
return nil, h.ArgErr()
|
return nil, h.ArgErr()
|
||||||
|
|
|
@ -115,7 +115,7 @@ func (routes RouteList) Provision(ctx caddy.Context) error {
|
||||||
// matchers
|
// matchers
|
||||||
matchersIface, err := ctx.LoadModule(&route, "MatcherSetsRaw")
|
matchersIface, err := ctx.LoadModule(&route, "MatcherSetsRaw")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("loadng matchers in route %d: %v", i, err)
|
return fmt.Errorf("loading matchers in route %d: %v", i, err)
|
||||||
}
|
}
|
||||||
err = routes[i].MatcherSets.FromInterface(matchersIface)
|
err = routes[i].MatcherSets.FromInterface(matchersIface)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
Loading…
Add table
Reference in a new issue