diff options
author | Unknwon <u@gogs.io> | 2016-07-01 15:33:35 +0800 |
---|---|---|
committer | Unknwon <u@gogs.io> | 2016-07-01 15:33:35 +0800 |
commit | 3a30c06345df40bf407a866b049ef649dfc8a745 (patch) | |
tree | 6115b496f3e3f72427d8f2e20b3a0358b98c7dcb /models | |
parent | a10ca2c5f6333cf725b0a17f7e3adb9a21700afe (diff) | |
download | gitea-3a30c06345df40bf407a866b049ef649dfc8a745.tar.gz gitea-3a30c06345df40bf407a866b049ef649dfc8a745.zip |
Fix wiki vulnerabilities
- Arbitrary file creation leading to command execution
- .md file creation/deletion
Reported by Gabriel Campana.
Diffstat (limited to 'models')
-rw-r--r-- | models/wiki.go | 17 |
1 files changed, 13 insertions, 4 deletions
diff --git a/models/wiki.go b/models/wiki.go index fee5a40814..39fb96dd5c 100644 --- a/models/wiki.go +++ b/models/wiki.go @@ -69,10 +69,12 @@ func ToWikiPageURL(name string) string { return url.QueryEscape(strings.Replace(name, " ", "-", -1)) } -// ToWikiPageName formats a URL back to corresponding wiki page name. +// ToWikiPageName formats a URL back to corresponding wiki page name, +// and removes leading characters './' to prevent changing files +// that are not belong to wiki repository. func ToWikiPageName(urlString string) string { name, _ := url.QueryUnescape(strings.Replace(urlString, "-", " ", -1)) - return name + return strings.Replace(strings.TrimLeft(name, "./"), "/", " ", -1) } // WikiCloneLink returns clone URLs of repository wiki. @@ -149,7 +151,7 @@ func (repo *Repository) updateWikiPage(doer *User, oldTitle, title, content, mes return fmt.Errorf("UpdateLocalWiki: %v", err) } - title = ToWikiPageName(strings.Replace(title, "/", " ", -1)) + title = ToWikiPageName(title) filename := path.Join(localPath, title+".md") // If not a new file, show perform update not create. @@ -161,6 +163,13 @@ func (repo *Repository) updateWikiPage(doer *User, oldTitle, title, content, mes os.Remove(path.Join(localPath, oldTitle+".md")) } + // SECURITY: if new file is a symlink to non-exist critical file, + // attack content can be written to the target file (e.g. authorized_keys2) + // as a new page operation. + // So we want to make sure the symlink is removed before write anything. + // The new file we created will be in normal text format. + os.Remove(filename) + if err = ioutil.WriteFile(filename, []byte(content), 0666); err != nil { return fmt.Errorf("WriteFile: %v", err) } @@ -198,7 +207,7 @@ func (repo *Repository) DeleteWikiPage(doer *User, title string) (err error) { return fmt.Errorf("UpdateLocalWiki: %v", err) } - title = ToWikiPageName(strings.Replace(title, "/", " ", -1)) + title = ToWikiPageName(title) filename := path.Join(localPath, title+".md") os.Remove(filename) |