diff options
author | Jason A. Donenfeld | 2018-08-03 15:46:11 +0200 |
---|---|---|
committer | Jason A. Donenfeld | 2018-08-03 17:04:03 +0200 |
commit | 53efaf30b50f095cad8c160488c74bba3e3b2680 (patch) | |
tree | 48c0be88bfef03400ddd4b3871baf9de9dbe0b77 | |
parent | c679d9010451b986bae719a6abe0458af2b2dfb9 (diff) | |
download | cgit-53efaf30b50f095cad8c160488c74bba3e3b2680.tar.gz cgit-53efaf30b50f095cad8c160488c74bba3e3b2680.tar.bz2 cgit-53efaf30b50f095cad8c160488c74bba3e3b2680.zip |
clone: fix directory traversal
This was introduced in the initial version of this code, way back when
in 2008.
$ curl http://127.0.0.1/cgit/repo/objects/?path=../../../../../../../../../etc/passwd
root:x:0:0:root:/root:/bin/sh
...
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
Reported-by: Jann Horn <jannh@google.com>
-rw-r--r-- | ui-clone.c | 23 |
1 files changed, 19 insertions, 4 deletions
@@ -92,17 +92,32 @@ void cgit_clone_info(void) | |||
92 | 92 | ||
93 | void cgit_clone_objects(void) | 93 | void cgit_clone_objects(void) |
94 | { | 94 | { |
95 | if (!ctx.qry.path) { | 95 | char *p; |
96 | cgit_print_error_page(400, "Bad request", "Bad request"); | 96 | |
97 | return; | 97 | if (!ctx.qry.path) |
98 | } | 98 | goto err; |
99 | 99 | ||
100 | if (!strcmp(ctx.qry.path, "info/packs")) { | 100 | if (!strcmp(ctx.qry.path, "info/packs")) { |
101 | print_pack_info(); | 101 | print_pack_info(); |
102 | return; | 102 | return; |
103 | } | 103 | } |
104 | 104 | ||
105 | /* Avoid directory traversal by forbidding "..", but also work around | ||
106 | * other funny business by just specifying a fairly strict format. For | ||
107 | * example, now we don't have to stress out about the Cygwin port. | ||
108 | */ | ||
109 | for (p = ctx.qry.path; *p; ++p) { | ||
110 | if (*p == '.' && *(p + 1) == '.') | ||
111 | goto err; | ||
112 | if (!isalnum(*p) && *p != '/' && *p != '.' && *p != '-') | ||
113 | goto err; | ||
114 | } | ||
115 | |||
105 | send_file(git_path("objects/%s", ctx.qry.path)); | 116 | send_file(git_path("objects/%s", ctx.qry.path)); |
117 | return; | ||
118 | |||
119 | err: | ||
120 | cgit_print_error_page(400, "Bad request", "Bad request"); | ||
106 | } | 121 | } |
107 | 122 | ||
108 | void cgit_clone_head(void) | 123 | void cgit_clone_head(void) |