]> granicus.if.org Git - cgit/commitdiff
ui-shared: prevent malicious filename from injecting headers
authorJason A. Donenfeld <Jason@zx2c4.com>
Thu, 14 Jan 2016 13:28:37 +0000 (14:28 +0100)
committerJason A. Donenfeld <Jason@zx2c4.com>
Thu, 14 Jan 2016 13:28:37 +0000 (14:28 +0100)
html.c
html.h
ui-shared.c

diff --git a/html.c b/html.c
index 959148ca612328a1a1e4c297212943ed30199f28..d89df3ae35e219fedaf28b4f61820c695af234f9 100644 (file)
--- a/html.c
+++ b/html.c
@@ -239,6 +239,32 @@ void html_url_arg(const char *txt)
                html(txt);
 }
 
+void html_header_arg_in_quotes(const char *txt)
+{
+       const char *t = txt;
+       while (t && *t) {
+               unsigned char c = *t;
+               const char *e = NULL;
+               if (c == '\\')
+                       e = "\\\\";
+               else if (c == '\r')
+                       e = "\\r";
+               else if (c == '\n')
+                       e = "\\n";
+               else if (c == '"')
+                       e = "\\\"";
+               if (e) {
+                       html_raw(txt, t - txt);
+                       html(e);
+                       txt = t + 1;
+               }
+               t++;
+       }
+       if (t != txt)
+               html(txt);
+
+}
+
 void html_hidden(const char *name, const char *value)
 {
        html("<input type='hidden' name='");
diff --git a/html.h b/html.h
index c5547631f850664b2ddfc01046c7fc3e50af687d..c72e845a7b6551c361e40815dec4795d8e986d23 100644 (file)
--- a/html.h
+++ b/html.h
@@ -23,6 +23,7 @@ extern void html_ntxt(int len, const char *txt);
 extern void html_attr(const char *txt);
 extern void html_url_path(const char *txt);
 extern void html_url_arg(const char *txt);
+extern void html_header_arg_in_quotes(const char *txt);
 extern void html_hidden(const char *name, const char *value);
 extern void html_option(const char *value, const char *text, const char *selected_value);
 extern void html_intoption(int value, const char *text, int selected_value);
index 21f581f07fbf98feba066796fd3d489dfd5efca7..54bbde757951df30824484969276578f8c0a8650 100644 (file)
@@ -692,9 +692,11 @@ void cgit_print_http_headers(void)
                htmlf("Content-Type: %s\n", ctx.page.mimetype);
        if (ctx.page.size)
                htmlf("Content-Length: %zd\n", ctx.page.size);
-       if (ctx.page.filename)
-               htmlf("Content-Disposition: inline; filename=\"%s\"\n",
-                     ctx.page.filename);
+       if (ctx.page.filename) {
+               html("Content-Disposition: inline; filename=\"");
+               html_header_arg_in_quotes(ctx.page.filename);
+               html("\"\n");
+       }
        if (!ctx.env.authenticated)
                html("Cache-Control: no-cache, no-store\n");
        htmlf("Last-Modified: %s\n", http_date(ctx.page.modified));