repo: stability improvements for rendering directory listing#8064
repo: stability improvements for rendering directory listing#8064
Conversation
There was a problem hiding this comment.
Pull request overview
This PR addresses a DoS vulnerability by implementing graceful error handling for git log operations that fail due to malicious input in filenames (e.g., filenames containing "[]"). The changes prevent application crashes by using fallback values when git operations fail.
Key changes:
- Modified error handling in wiki operations to use dummy author/timestamp data instead of failing
- Replaced batch commit info fetching with individual file processing that skips problematic files
- Removed unused
timepackage import from view.go
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 12 comments.
| File | Description |
|---|---|
| internal/route/repo/wiki.go | Added fallback handling for failed git log operations in both Wiki() and WikiPages() functions, using dummy author/timestamp values instead of returning errors |
| internal/route/repo/view.go | Replaced batch CommitsInfo() call with individual CommitByPath() calls that skip files on error, and removed unused time import |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
You can also share your feedback on Copilot code review for a chance to win a $100 gift card. Take the survey.
internal/route/repo/wiki.go
Outdated
| if err != nil || len(commits) == 0{ | ||
| //c.Error(err, "get commits by path") | ||
|
|
||
| // sets dummy commit time to prevent failure | ||
| name := strings.TrimSuffix(entries[i].Name(), ".md") | ||
| pages = append(pages, PageMeta{ | ||
| Name: name, | ||
| URL: database.ToWikiPageURL(name), | ||
| Updated: time.Unix(0,0), | ||
| }) | ||
| } else { | ||
| name := strings.TrimSuffix(entries[i].Name(), ".md") | ||
| pages = append(pages, PageMeta{ | ||
| Name: name, | ||
| URL: database.ToWikiPageURL(name), | ||
| Updated: commits[0].Author.When, | ||
| }) |
There was a problem hiding this comment.
The error handling condition if err != nil || len(commits) == 0 treats both actual errors and empty commit lists the same way. An empty commit list is not necessarily an error condition - it could be a legitimate state for a newly created file. Consider handling these cases separately to avoid masking real errors.
| if err != nil || len(commits) == 0{ | |
| //c.Error(err, "get commits by path") | |
| // sets dummy commit time to prevent failure | |
| name := strings.TrimSuffix(entries[i].Name(), ".md") | |
| pages = append(pages, PageMeta{ | |
| Name: name, | |
| URL: database.ToWikiPageURL(name), | |
| Updated: time.Unix(0,0), | |
| }) | |
| } else { | |
| name := strings.TrimSuffix(entries[i].Name(), ".md") | |
| pages = append(pages, PageMeta{ | |
| Name: name, | |
| URL: database.ToWikiPageURL(name), | |
| Updated: commits[0].Author.When, | |
| }) | |
| if err != nil { | |
| // Handle actual error (optionally log or skip this entry) | |
| //c.Error(err, "get commits by path") | |
| continue | |
| } | |
| if len(commits) == 0 { | |
| // sets dummy commit time to prevent failure | |
| name := strings.TrimSuffix(entries[i].Name(), ".md") | |
| pages = append(pages, PageMeta{ | |
| Name: name, | |
| URL: database.ToWikiPageURL(name), | |
| Updated: time.Unix(0,0), | |
| }) | |
| } else { | |
| name := strings.TrimSuffix(entries[i].Name(), ".md") | |
| pages = append(pages, PageMeta{ | |
| Name: name, | |
| URL: database.ToWikiPageURL(name), | |
| Updated: commits[0].Author.When, | |
| }) |
|
Hey @0xless, thanks for the PR! Could you take a look at Copilot's comments: if valid, address the feedback; if not, explain why? |
Also the link here seems to be incorrect? i.e., it is currently pointing to a unrelated PR. |
Fixed the link issue. I'll check the comments as soon as I have some time to dedicate to the project. I honestly missed the comments at the time. |
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
|
I've solved most issues pointed by copilot, function for rendering wiki page listing might be non-optimized, but I was not able to solve the issue in other ways. Hope this works for you. |
|
Thanks for the followup! Before diving into reviewing the current approach, I want to take a step back and clarify on the original issue. In the GHSA, Gogs wouldn't be able to get blob info because the path contains special characters, the approach in this PR is to simply ignore all failed reads. Couldn't we escape those special characters before sending to Git so they are not mistaken as pathspec (or whatever)? |
@unknwon I sent you an email a while ago detailing what's necessary to do to achieve so, here is an extract: It depends on you if you prefer applying the PR I submitted to have the issue temporarily fixed while work on the git-module is done, or if you want to implement the fix directly in git-module. Right now the fix in the PR will use dummy commit data for files in the wiki and ignore "broken" file entries for files in a repository. Let me know what you think. |
|
Ah yeah I remember that email. Skimming through that link, it seems to have the --literal-pathspecs, which says
May not be what we think but looks like worth a try (and maybe other ones too). Let's aiming for a "fix" if possible and if we truly can't, we will fall back to "ignore" approach proposed in this PR. Do you wanna give it a try or else I can take a look (takes about a few days to months 😂 still need to prioritize a patch release). |
|
I think I got this problem addressed in #8116? |
|
Hi @unknwon , I was able to pull and test the latest version of gogs ( There is an improvement in wiki file listing rendering as the malicious filename Additionally I couldn't find any differences in behavior in repo file listings as filename Given these issues, I wouldn't consider the fix to be complete. Are you able to confirm these behaviors? I wasn't considering it at first as it would restrict the allowed charset for filenames, but what do you think about filtering out any non-alphanumeric character from the filenames? (Maybe still allowing chars Let me know what you think. Best, |
|
@unknwon I was able to reproduce with title I confirm the issue with repository files (not wiki files) is still present as well. On another topic, what do you think of this solution?
|
|
Thanks! Will check, meanwhile could you share the exact steps to recreate the wiki you shared? Re: quote People can always git push there is no way we can reject creation of them 100%. The rejection of symlink is via web editing only which prevents server-side traversal and that’s the root cause. Git push with symlink is safe. |
Yeah fair. Anyway, to reproduce the issue in wiki (page not shown in listing) you need to:
Hope this helps. |
|
Did you create the page via web UI or push from local? I created via web UI seems not hitting the issue. Could you share the exact commands you used? |


Describe the pull request
Gracefully handles failed git log operations due to malicious input in filenames.
Link to the issue: DoS sssue
Checklist
Test plan
Create a new file in a repository with a filename containing payload
"[], do the same for a wiki file.More details at: DoS issue
Edit: use payload
"[] barfor wiki files.