summaryrefslogtreecommitdiff
path: root/modules/caddyhttp/fileserver/staticfiles_test.go
diff options
context:
space:
mode:
Diffstat (limited to 'modules/caddyhttp/fileserver/staticfiles_test.go')
-rw-r--r--modules/caddyhttp/fileserver/staticfiles_test.go81
1 files changed, 81 insertions, 0 deletions
diff --git a/modules/caddyhttp/fileserver/staticfiles_test.go b/modules/caddyhttp/fileserver/staticfiles_test.go
new file mode 100644
index 0000000..2a99c71
--- /dev/null
+++ b/modules/caddyhttp/fileserver/staticfiles_test.go
@@ -0,0 +1,81 @@
+package fileserver
+
+import (
+ "net/url"
+ "testing"
+)
+
+func TestSanitizedPathJoin(t *testing.T) {
+ // For easy reference:
+ // %2E = .
+ // %2F = /
+ // %5C = \
+ for i, tc := range []struct {
+ inputRoot string
+ inputPath string
+ expect string
+ }{
+ {
+ inputPath: "",
+ expect: ".",
+ },
+ {
+ inputPath: "/",
+ expect: ".",
+ },
+ {
+ inputPath: "/foo",
+ expect: "foo",
+ },
+ {
+ inputPath: "/foo/bar",
+ expect: "foo/bar",
+ },
+ {
+ inputRoot: "/a",
+ inputPath: "/foo/bar",
+ expect: "/a/foo/bar",
+ },
+ {
+ inputPath: "/foo/../bar",
+ expect: "bar",
+ },
+ {
+ inputRoot: "/a/b",
+ inputPath: "/foo/../bar",
+ expect: "/a/b/bar",
+ },
+ {
+ inputRoot: "/a/b",
+ inputPath: "/..%2fbar",
+ expect: "/a/b/bar",
+ },
+ {
+ inputRoot: "/a/b",
+ inputPath: "/%2e%2e%2fbar",
+ expect: "/a/b/bar",
+ },
+ {
+ inputRoot: "/a/b",
+ inputPath: "/%2e%2e%2f%2e%2e%2f",
+ expect: "/a/b",
+ },
+ // TODO: test windows paths... on windows... sigh.
+ } {
+ // we don't *need* to use an actual parsed URL, but it
+ // adds some authenticity to the tests since real-world
+ // values will be coming in from URLs; thus, the test
+ // corpus can contain paths as encoded by clients, which
+ // more closely emulates the actual attack vector
+ u, err := url.Parse("http://test:9999" + tc.inputPath)
+ if err != nil {
+ t.Fatalf("Test %d: invalid URL: %v", i, err)
+ }
+ actual := sanitizedPathJoin(tc.inputRoot, u.Path)
+ if actual != tc.expect {
+ t.Errorf("Test %d: [%s %s] => %s (expected %s)", i, tc.inputRoot, tc.inputPath, actual, tc.expect)
+ }
+ }
+}
+
+// TODO: test fileHidden