diff options
| -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) |
