summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorMatthew Holt <[email protected]>2017-05-02 11:20:50 -0600
committerMatthew Holt <[email protected]>2017-05-02 11:20:50 -0600
commit59a5afab292046b67526b6f38582d3a0efbfcc50 (patch)
tree4b0630fdde8a6a73623e2fa4d16d1a863b33bc89
parentd8fb2ddc2de33857acf294a050633b6b2560b93e (diff)
downloadcaddy-59a5afab292046b67526b6f38582d3a0efbfcc50.tar.gz
caddy-59a5afab292046b67526b6f38582d3a0efbfcc50.zip
fastcgi: Prepend missing leading slash when matching paths (see #1645)
httpserver: More path matching tests
-rw-r--r--caddyhttp/fastcgi/fastcgi.go22
-rw-r--r--caddyhttp/httpserver/path_test.go39
2 files changed, 56 insertions, 5 deletions
diff --git a/caddyhttp/fastcgi/fastcgi.go b/caddyhttp/fastcgi/fastcgi.go
index ca9eeb8d2..4cd34fc6f 100644
--- a/caddyhttp/fastcgi/fastcgi.go
+++ b/caddyhttp/fastcgi/fastcgi.go
@@ -36,9 +36,25 @@ type Handler struct {
// ServeHTTP satisfies the httpserver.Handler interface.
func (h Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) (int, error) {
for _, rule := range h.Rules {
-
- // First requirement: Base path must match and the path must be allowed.
- if !httpserver.Path(r.URL.Path).Matches(rule.Path) || !rule.AllowedPath(r.URL.Path) {
+ // First requirement: Base path must match request path. If it doesn't,
+ // we check to make sure the leading slash is not missing, and if so,
+ // we check again with it prepended. This is in case people forget
+ // a leading slash when performing rewrites, and we don't want to expose
+ // the contents of the (likely PHP) script. See issue #1645.
+ hpath := httpserver.Path(r.URL.Path)
+ if !hpath.Matches(rule.Path) {
+ if strings.HasPrefix(string(hpath), "/") {
+ // this is a normal-looking path, and it doesn't match; try next rule
+ continue
+ }
+ hpath = httpserver.Path("/" + string(hpath)) // prepend leading slash
+ if !hpath.Matches(rule.Path) {
+ // even after fixing the request path, it still doesn't match; try next rule
+ continue
+ }
+ }
+ // The path must also be allowed (not ignored).
+ if !rule.AllowedPath(r.URL.Path) {
continue
}
diff --git a/caddyhttp/httpserver/path_test.go b/caddyhttp/httpserver/path_test.go
index 4e46cbe6b..6ae92e8f1 100644
--- a/caddyhttp/httpserver/path_test.go
+++ b/caddyhttp/httpserver/path_test.go
@@ -5,7 +5,7 @@ import "testing"
func TestPathMatches(t *testing.T) {
for i, testcase := range []struct {
reqPath Path
- rulePath string
+ rulePath string // or "base path" as in Caddyfile docs
shouldMatch bool
caseInsensitive bool
}{
@@ -48,7 +48,42 @@ func TestPathMatches(t *testing.T) {
},
{
reqPath: "",
- rulePath: "/", // a lone forward slash means to match all requests (see issue #1645)
+ rulePath: "/", // a lone forward slash means to match all requests (see issue #1645) - many future test cases related to this issue
+ shouldMatch: true,
+ },
+ {
+ reqPath: "foobar.php",
+ rulePath: "/",
+ shouldMatch: true,
+ },
+ {
+ reqPath: "",
+ rulePath: "",
+ shouldMatch: true,
+ },
+ {
+ reqPath: "/foo/bar",
+ rulePath: "",
+ shouldMatch: true,
+ },
+ {
+ reqPath: "/foo/bar",
+ rulePath: "",
+ shouldMatch: true,
+ },
+ {
+ reqPath: "no/leading/slash",
+ rulePath: "/",
+ shouldMatch: true,
+ },
+ {
+ reqPath: "no/leading/slash",
+ rulePath: "/no/leading/slash",
+ shouldMatch: false,
+ },
+ {
+ reqPath: "no/leading/slash",
+ rulePath: "",
shouldMatch: true,
},
} {