mirror of
				https://github.com/caddyserver/caddy.git
				synced 2025-10-31 02:27:19 -04: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
					
				| @ -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…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user