commit d927f8c8203baf6607d4e64fa3520e2d164100e6 from: Omar Polo date: Sat Aug 20 13:58:05 2022 UTC gotwebd: make sure to escape possibly unsafe strings this fixes only the HTML escaping of strings, the urlencode is still missig. while here also plug a memory leak in gotweb_render_branches and drop some needless ternary operators. ok tracey@ commit - 336c64e8b8d86804e345f9ad6cd5e9690768d48d commit + d927f8c8203baf6607d4e64fa3520e2d164100e6 blob - 35735937cc54916d0fa7248397a0a66248c0c510 blob + 18dca123b78589b4efb8482bc4caa54e1aae7176 --- gotwebd/got_operations.c +++ gotwebd/got_operations.c @@ -830,7 +830,7 @@ got_output_repo_tree(struct request *c) struct got_tree_object *tree = NULL; struct repo_dir *repo_dir = t->repo_dir; const char *name, *index_page_str, *folder; - char *id_str = NULL; + char *id_str = NULL, *escaped_name; char *path = NULL, *in_repo_path = NULL, *modestr = NULL; int nentries, i, r; @@ -920,8 +920,12 @@ got_output_repo_tree(struct request *c) } } + name = got_tree_entry_get_name(te); + error = gotweb_escape_html(&escaped_name, name); + if (error) + goto done; + if (S_ISDIR(mode)) { - name = got_tree_entry_get_name(te); r = fcgi_printf(c, "
\n" "
" @@ -932,11 +936,10 @@ got_output_repo_tree(struct request *c) "
 
\n" "
\n", /* .tree_wrapper */ index_page_str, qs->path, rc->commit_id, - folder, name, name, modestr); + folder, name, escaped_name, modestr); if (r == -1) goto done; } else { - name = got_tree_entry_get_name(te); r = fcgi_printf(c, "
\n" "
" @@ -952,7 +955,7 @@ got_output_repo_tree(struct request *c) "
\n" /* .tree_line_blank */ "
\n", /* .tree_wrapper */ index_page_str, qs->path, rc->commit_id, - folder, name, name, modestr, + folder, name, escaped_name, modestr, index_page_str, qs->path, rc->commit_id, folder, name, index_page_str, qs->path, rc->commit_id, blob - cdcadbcebe3a3e2d2650d7347672c6b37d2d468f blob + 0c7f7f7bb282446556c78d5ae4e4efe47c63b19d --- gotwebd/gotweb.c +++ gotwebd/gotweb.c @@ -1136,7 +1136,7 @@ gotweb_render_blame(struct request *c) const struct got_error *error = NULL; struct transport *t = c->t; struct repo_commit *rc = NULL; - char *age = NULL; + char *age = NULL, *msg = NULL; int r; error = got_get_repo_commits(c, 1); @@ -1146,6 +1146,9 @@ gotweb_render_blame(struct request *c) rc = TAILQ_FIRST(&t->repo_commits); error = gotweb_get_time_str(&age, rc->committer_time, TM_LONG); + if (error) + goto done; + error = gotweb_escape_html(&msg, rc->commit_msg); if (error) goto done; @@ -1164,7 +1167,7 @@ gotweb_render_blame(struct request *c) "
\n" "
\n", age ? age : "", - rc->commit_msg); + msg); if (r == -1) goto done; @@ -1175,6 +1178,7 @@ gotweb_render_blame(struct request *c) fcgi_printf(c, "
\n" /* #blame */ "
\n"); /* #blame_content */ done: + free(msg); return error; } @@ -1189,7 +1193,7 @@ gotweb_render_briefs(struct request *c) struct repo_dir *repo_dir = t->repo_dir; const char *index_page_str; char *smallerthan, *newline; - char *age = NULL; + char *age = NULL, *author = NULL, *msg = NULL; int r; index_page_str = qs->index_page_str ? qs->index_page_str : ""; @@ -1222,22 +1226,34 @@ gotweb_render_briefs(struct request *c) if (newline) *newline = '\0'; + error = gotweb_escape_html(&author, rc->author); + if (error) + goto done; + error = gotweb_escape_html(&msg, rc->commit_msg); + if (error) + goto done; + r = fcgi_printf(c, "
%s
\n" "
%s
\n" "
" "%s", age ? age : "", - rc->author, + author, index_page_str, repo_dir->name, rc->commit_id, qs->headref, - rc->commit_msg); + msg); if (r == -1) goto done; if (rc->refs_str) { + char *refs; + + error = gotweb_escape_html(&refs, rc->refs_str); + if (error) + goto done; r = fcgi_printf(c, - " (%s)", - rc->refs_str); + " (%s)", refs); + free(refs); if (r == -1) goto done; } @@ -1261,6 +1277,10 @@ gotweb_render_briefs(struct request *c) free(age); age = NULL; + free(author); + author = NULL; + free(msg); + msg = NULL; } if (t->next_id || t->prev_id) { @@ -1271,6 +1291,8 @@ gotweb_render_briefs(struct request *c) fcgi_printf(c, "
\n"); /* #briefs_content */ done: free(age); + free(author); + free(msg); return error; } @@ -1284,7 +1306,7 @@ gotweb_render_commits(struct request *c) struct querystring *qs = t->qs; struct repo_dir *repo_dir = t->repo_dir; const char *index_page_str; - char *age = NULL, *author = NULL; + char *age = NULL, *author = NULL, *msg = NULL; int r; index_page_str = qs->index_page_str ? qs->index_page_str : ""; @@ -1307,6 +1329,9 @@ gotweb_render_commits(struct request *c) error = gotweb_escape_html(&author, rc->author); if (error) goto done; + error = gotweb_escape_html(&msg, rc->commit_msg); + if (error) + goto done; r = fcgi_printf(c, "
\n" "
\n" @@ -1321,9 +1346,9 @@ gotweb_render_commits(struct request *c) "
\n" "
\n%s
\n", rc->commit_id, - author ? author : "", + author, age ? age : "", - rc->commit_msg); + msg); if (r == -1) goto done; @@ -1344,6 +1369,8 @@ gotweb_render_commits(struct request *c) age = NULL; free(author); author = NULL; + free(msg); + msg = NULL; } if (t->next_id || t->prev_id) { @@ -1354,6 +1381,8 @@ gotweb_render_commits(struct request *c) fcgi_printf(c, "
\n"); /* .commits_content */ done: free(age); + free(author); + free(msg); return error; } @@ -1387,12 +1416,13 @@ gotweb_render_branches(struct request *c) goto done; TAILQ_FOREACH(re, &refs, entry) { - char *refname = NULL; + const char *refname = NULL; + char *escaped_refname = NULL; if (got_ref_is_symbolic(re->ref)) continue; - refname = strdup(got_ref_get_name(re->ref)); + refname = got_ref_get_name(re->ref); if (refname == NULL) { error = got_error_from_errno("strdup"); goto done; @@ -1407,6 +1437,9 @@ gotweb_render_branches(struct request *c) if (strncmp(refname, "refs/heads/", 11) == 0) refname += 11; + error = gotweb_escape_html(&escaped_refname, refname); + if (error) + goto done; r = fcgi_printf(c, "
\n" "
%s
\n" @@ -1431,10 +1464,11 @@ gotweb_render_branches(struct request *c) "
\n", /* .branches_wrapper */ age ? age : "", index_page_str, qs->path, refname, - refname, + escaped_refname, index_page_str, qs->path, refname, index_page_str, qs->path, refname, index_page_str, qs->path, refname); + free(escaped_refname); if (r == -1) goto done; @@ -1453,7 +1487,7 @@ gotweb_render_tree(struct request *c) const struct got_error *error = NULL; struct transport *t = c->t; struct repo_commit *rc = NULL; - char *age = NULL; + char *age = NULL, *msg = NULL; int r; error = got_get_repo_commits(c, 1); @@ -1466,6 +1500,10 @@ gotweb_render_tree(struct request *c) if (error) goto done; + error = gotweb_escape_html(&msg, rc->commit_msg); + if (error) + goto done; + r = fcgi_printf(c, "
\n" "
Tree
\n" "
\n" /* #tree_title_wrapper */ @@ -1484,7 +1522,7 @@ gotweb_render_tree(struct request *c) "
\n", rc->tree_id, age ? age : "", - rc->commit_msg); + msg); if (r == -1) goto done; @@ -1495,6 +1533,7 @@ gotweb_render_tree(struct request *c) fcgi_printf(c, "
\n"); /* #tree */ fcgi_printf(c, "
\n"); /* #tree_content */ done: + free(msg); return error; } @@ -1504,7 +1543,7 @@ gotweb_render_diff(struct request *c) const struct got_error *error = NULL; struct transport *t = c->t; struct repo_commit *rc = NULL; - char *age = NULL, *author = NULL; + char *age = NULL, *author = NULL, *msg = NULL; int r; error = got_get_repo_commits(c, 1); @@ -1519,6 +1558,9 @@ gotweb_render_diff(struct request *c) error = gotweb_escape_html(&author, rc->author); if (error) goto done; + error = gotweb_escape_html(&msg, rc->commit_msg); + if (error) + goto done; r = fcgi_printf(c, "
\n" "
Commit Diff
\n" @@ -1545,9 +1587,9 @@ gotweb_render_diff(struct request *c) rc->parent_id, rc->commit_id, rc->commit_id, rc->tree_id, - author ? author : "", + author, age ? age : "", - rc->commit_msg); + msg); if (r == -1) goto done; @@ -1560,6 +1602,7 @@ gotweb_render_diff(struct request *c) done: free(age); free(author); + free(msg); return error; } @@ -1639,7 +1682,7 @@ gotweb_render_tag(struct request *c) const struct got_error *error = NULL; struct repo_tag *rt = NULL; struct transport *t = c->t; - char *age = NULL, *author = NULL; + char *tagname = NULL, *age = NULL, *author = NULL, *msg = NULL; error = got_get_repo_tags(c, 1); if (error) @@ -1659,9 +1702,15 @@ gotweb_render_tag(struct request *c) error = gotweb_escape_html(&author, rt->tagger); if (error) goto done; + error = gotweb_escape_html(&msg, rt->commit_msg); + if (error) + goto done; if (strncmp(rt->tag_name, "refs/", 5) == 0) rt->tag_name += 5; + error = gotweb_escape_html(&tagname, rt->tag_name); + if (error) + goto done; fcgi_printf(c, "
\n" "
Tag
\n" @@ -1683,15 +1732,16 @@ gotweb_render_tag(struct request *c) "
\n%s
" "
", /* tag_header_wrapper */ rt->commit_id, - rt->tag_name, - author ? author : "", + tagname, + author, age ? age : "", - rt->commit_msg, + msg, rt->tag_commit); done: free(age); free(author); + free(msg); return error; } @@ -1705,8 +1755,7 @@ gotweb_render_tags(struct request *c) struct querystring *qs = t->qs; struct repo_dir *repo_dir = t->repo_dir; const char *index_page_str; - char *newline; - char *age = NULL; + char *age = NULL, *tagname = NULL, *msg = NULL, *newline; int r, commit_found = 0; index_page_str = qs->index_page_str ? qs->index_page_str : ""; @@ -1746,11 +1795,17 @@ gotweb_render_tags(struct request *c) if (strncmp(rt->tag_name, "refs/tags/", 10) == 0) rt->tag_name += 10; + error = gotweb_escape_html(&tagname, rt->tag_name); + if (error) + goto done; if (rt->tag_commit != NULL) { newline = strchr(rt->tag_commit, '\n'); if (newline) *newline = '\0'; + error = gotweb_escape_html(&msg, rt->tag_commit); + if (error) + goto done; } r = fcgi_printf(c, "
%s
\n" @@ -1773,9 +1828,9 @@ gotweb_render_tags(struct request *c) "
\n" /* .navs_wrapper */ "
\n", age ? age : "", - rt->tag_name, + tagname, index_page_str, repo_dir->name, rt->commit_id, - rt->tag_commit ? rt->tag_commit : "", + msg ? msg : "", index_page_str, repo_dir->name, rt->commit_id, index_page_str, repo_dir->name, rt->commit_id, index_page_str, repo_dir->name, rt->commit_id); @@ -1784,6 +1839,10 @@ gotweb_render_tags(struct request *c) free(age); age = NULL; + free(tagname); + tagname = NULL; + free(msg); + msg = NULL; } if (t->next_id || t->prev_id) { error = gotweb_render_navs(c); @@ -1793,6 +1852,8 @@ gotweb_render_tags(struct request *c) fcgi_printf(c, "\n"); /* #tags_content */ done: free(age); + free(tagname); + free(msg); return error; }