summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMatt Burke <spraints@gmail.com>2015-09-10 09:11:16 -0400
committerMatt Burke <spraints@gmail.com>2015-09-10 09:11:16 -0400
commit8c876fa91d0783bf4e1f0e624b2dfa86574de4e3 (patch)
treee1d6e89006110496db436c6f03f0a8ad2f46417a /src
parent35969c6839c0659ed3ced67bfc5b963662a721f2 (diff)
downloadlibgit2-8c876fa91d0783bf4e1f0e624b2dfa86574de4e3.tar.gz
Validate custom http headers
Diffstat (limited to 'src')
-rw-r--r--src/transports/smart.c53
1 files changed, 53 insertions, 0 deletions
diff --git a/src/transports/smart.c b/src/transports/smart.c
index 15f45e11c..ee49729aa 100644
--- a/src/transports/smart.c
+++ b/src/transports/smart.c
@@ -66,11 +66,64 @@ static int git_smart__set_callbacks(
return 0;
}
+bool is_valid(const char *custom_header)
+{
+ const char *c;
+ int name_len;
+
+ if (custom_header == NULL)
+ return true;
+
+ // Disallow \r and \n
+ c = strchr(custom_header, '\r');
+ if (c != NULL)
+ return false;
+ c = strchr(custom_header, '\n');
+ if (c != NULL)
+ return false;
+
+ // Require a header name followed by :
+ c = strchr(custom_header, ':');
+ if (c == NULL)
+ return false;
+ name_len = c - custom_header;
+ if (name_len < 1)
+ return false;
+
+ // Disallow headers that we set
+ return git__strncmp("User-Agent", custom_header, name_len) == 0 &&
+ git__strncmp("Host", custom_header, name_len) == 0 &&
+ git__strncmp("Accept", custom_header, name_len) == 0 &&
+ git__strncmp("Content-Type", custom_header, name_len) == 0 &&
+ git__strncmp("Transfer-Encoding", custom_header, name_len) == 0 &&
+ git__strncmp("Content-Length", custom_header, name_len) == 0;
+}
+
+const char *find_invalid_header(const git_strarray *custom_headers)
+{
+ size_t i;
+
+ if (custom_headers == NULL || custom_headers->count == 0)
+ return NULL;
+
+ for (i = 0; i < custom_headers->count; i++)
+ if (!is_valid(custom_headers->strings[i]))
+ return custom_headers->strings[i];
+
+ return NULL;
+}
+
static int git_smart__set_custom_headers(
git_transport *transport,
const git_strarray *custom_headers)
{
transport_smart *t = (transport_smart *)transport;
+ const char *invalid_header = find_invalid_header(custom_headers);
+
+ if (invalid_header != NULL) {
+ giterr_set(GITERR_INVALID, "Illegal HTTP header '%s'", invalid_header);
+ return -1;
+ }
t->custom_headers = custom_headers;