cgit

commit c326f3eb026d67650f79a6dda9a1a42c55d10a25

Author: Jason A. Donenfeld <Jason@zx2c4.com>

ui-plain: add enable-html-serving flag

Unrestricts plain/ to contents likely to be executed by browser.

 cgit.c | 5 +++++
 cgit.h | 2 ++
 cgitrc.5.txt | 11 +++++++++++
 shared.c | 1 +
 ui-plain.c | 10 ++++++++++


diff --git a/cgit.c b/cgit.c
index 3ed1935c1eb4eb5561ccaed3f9d169b72286ca90..7f83a2dbb0985c614e129a41f7a5975feee9686d 100644
--- a/cgit.c
+++ b/cgit.c
@@ -55,6 +55,8 @@ 	else if (!strcmp(name, "enable-remote-branches"))
 		repo->enable_remote_branches = atoi(value);
 	else if (!strcmp(name, "enable-subject-links"))
 		repo->enable_subject_links = atoi(value);
+	else if (!strcmp(name, "enable-html-serving"))
+		repo->enable_html_serving = atoi(value);
 	else if (!strcmp(name, "branch-sort")) {
 		if (!strcmp(value, "age"))
 			repo->branch_sort = 1;
@@ -170,6 +172,8 @@ 	else if (!strcmp(name, "enable-remote-branches"))
 		ctx.cfg.enable_remote_branches = atoi(value);
 	else if (!strcmp(name, "enable-subject-links"))
 		ctx.cfg.enable_subject_links = atoi(value);
+	else if (!strcmp(name, "enable-html-serving"))
+		ctx.cfg.enable_html_serving = atoi(value);
 	else if (!strcmp(name, "enable-tree-linenumbers"))
 		ctx.cfg.enable_tree_linenumbers = atoi(value);
 	else if (!strcmp(name, "enable-git-config"))
@@ -821,6 +825,7 @@ 	if (repo->logo_link)
 		fprintf(f, "repo.logo-link=%s\n", repo->logo_link);
 	fprintf(f, "repo.enable-remote-branches=%d\n", repo->enable_remote_branches);
 	fprintf(f, "repo.enable-subject-links=%d\n", repo->enable_subject_links);
+	fprintf(f, "repo.enable-html-serving=%d\n", repo->enable_html_serving);
 	if (repo->branch_sort == 1)
 		fprintf(f, "repo.branch-sort=age\n");
 	if (repo->commit_sort) {




diff --git a/cgit.h b/cgit.h
index 4b4bcf4b9cb30bda303ac9b597313be667e93274..de5c94a1862692f19f35a66f38f4c24e80dad247 100644
--- a/cgit.h
+++ b/cgit.h
@@ -101,6 +101,7 @@ 	int enable_log_filecount;
 	int enable_log_linecount;
 	int enable_remote_branches;
 	int enable_subject_links;
+	int enable_html_serving;
 	int max_stats;
 	int branch_sort;
 	int commit_sort;
@@ -235,6 +236,7 @@ 	int enable_log_filecount;
 	int enable_log_linecount;
 	int enable_remote_branches;
 	int enable_subject_links;
+	int enable_html_serving;
 	int enable_tree_linenumbers;
 	int enable_git_config;
 	int local_time;




diff --git a/cgitrc.5.txt b/cgitrc.5.txt
index 759f353efaf7651d0372e64e8501a30c2398ee38..47850a8003df969c38c78df067e7610dc37bb1ea 100644
--- a/cgitrc.5.txt
+++ b/cgitrc.5.txt
@@ -190,6 +190,13 @@ 	parent commit as link text when generating links to parent commits
 	in commit view. Default value: "0". See also:
 	"repo.enable-subject-links".
 
+enable-html-serving::
+	Flag which, when set to "1", will allow the /plain handler to serve
+	mimetype headers that result in the file being treated as HTML by the
+	browser. When set to "0", such file types are returned instead as
+	text/plain or application/octet-stream. Default value: "0". See also:
+	"repo.enable-html-serving".
+
 enable-tree-linenumbers::
 	Flag which, when set to "1", will make cgit generate linenumber links
 	for plaintext blobs printed in the tree view. Default value: "1".
@@ -512,6 +519,10 @@
 repo.enable-subject-links::
 	A flag which can be used to override the global setting
 	`enable-subject-links'. Default value: none.
+
+enable-html-serving::
+	A flag which can be used to override the global setting
+	`enable-html-serving`. Default value: none.
 
 repo.hide::
 	Flag which, when set to "1", hides the repository from the repository




diff --git a/shared.c b/shared.c
index 42b2ddc25ea90328fd3f2b08eb73929012df3098..a078a27b1bcc2accf5982ae8d1af005f728bac4c 100644
--- a/shared.c
+++ b/shared.c
@@ -61,6 +61,7 @@ 	ret->enable_log_filecount = ctx.cfg.enable_log_filecount;
 	ret->enable_log_linecount = ctx.cfg.enable_log_linecount;
 	ret->enable_remote_branches = ctx.cfg.enable_remote_branches;
 	ret->enable_subject_links = ctx.cfg.enable_subject_links;
+	ret->enable_html_serving = ctx.cfg.enable_html_serving;
 	ret->max_stats = ctx.cfg.max_stats;
 	ret->branch_sort = ctx.cfg.branch_sort;
 	ret->commit_sort = ctx.cfg.commit_sort;




diff --git a/ui-plain.c b/ui-plain.c
index 58addab946af588fcb458026f9e7f5f731e6c7f5..ff85113718464ddbcf68af205a2fae1b6e3e86d1 100644
--- a/ui-plain.c
+++ b/ui-plain.c
@@ -37,6 +37,16 @@
 	mimetype = get_mimetype_for_filename(path);
 	ctx.page.mimetype = mimetype;
 
+	if (!ctx.repo->enable_html_serving) {
+		html("X-Content-Type-Options: nosniff\n");
+		html("Content-Security-Policy: default-src 'none'\n");
+		if (mimetype) {
+			/* Built-in white list allows PDF and everything that isn't text/ and application/ */
+			if ((!strncmp(mimetype, "text/", 5) || !strncmp(mimetype, "application/", 12)) && strcmp(mimetype, "application/pdf"))
+				ctx.page.mimetype = NULL;
+		}
+	}
+
 	if (!ctx.page.mimetype) {
 		if (buffer_is_binary(buf, size)) {
 			ctx.page.mimetype = "application/octet-stream";