more robust path traversal prevention
This commit is contained in:
parent
5b506f06d0
commit
2ed7370c2c
2 changed files with 44 additions and 24 deletions
|
@ -89,12 +89,12 @@ func (self *EurekaAdapter) ListPages() map[string]string {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *EurekaAdapter) GetPage(filename string) Page {
|
func (self *EurekaAdapter) GetPage(filename string) Page {
|
||||||
if strings.Contains(filename, "../") || strings.Contains(filename, "..\\") {
|
fullPath := filepath.Join(self.Root, "inc", filename)
|
||||||
|
if !strings.HasPrefix(filepath.Clean(fullPath), self.Root) {
|
||||||
return Page{
|
return Page{
|
||||||
Error: "You cannot escape!",
|
Error: "You cannot escape!",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fullPath := filepath.Join(self.Root, "inc", filename)
|
|
||||||
f, err := os.ReadFile(fullPath)
|
f, err := os.ReadFile(fullPath)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -199,8 +199,8 @@ func (self *EurekaAdapter) CreatePage(slug, title, content string) error {
|
||||||
slug = strings.ToLower(strings.ReplaceAll(title, " ", "_")) + ".htm"
|
slug = strings.ToLower(strings.ReplaceAll(title, " ", "_")) + ".htm"
|
||||||
path := filepath.Join(self.Root, "inc", slug)
|
path := filepath.Join(self.Root, "inc", slug)
|
||||||
|
|
||||||
if strings.Contains(slug, "../") || strings.Contains(slug, "..\\") {
|
if !strings.HasPrefix(filepath.Clean(path), self.Root) {
|
||||||
return errors.New("You cannot escape!")
|
errors.New("You cannot escape!")
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err := os.Stat(path)
|
_, err := os.Stat(path)
|
||||||
|
@ -220,8 +220,11 @@ func (self *EurekaAdapter) SavePage(oldSlug, newSlug, title, content string) err
|
||||||
// eureka creates titles from slugs, so we transform the title into the slug
|
// eureka creates titles from slugs, so we transform the title into the slug
|
||||||
newSlug = strings.ToLower(strings.ReplaceAll(title, " ", "_")) + ".htm"
|
newSlug = strings.ToLower(strings.ReplaceAll(title, " ", "_")) + ".htm"
|
||||||
|
|
||||||
if strings.Contains(newSlug, "../") || strings.Contains(newSlug, "..\\") ||
|
oldPath := filepath.Join(self.Root, "inc", oldSlug)
|
||||||
strings.Contains(oldSlug, "../") || strings.Contains(oldSlug, "..\\") {
|
newPath := filepath.Join(self.Root, "inc", newSlug)
|
||||||
|
|
||||||
|
if !strings.HasPrefix(filepath.Clean(oldPath), filepath.Join(self.Root, "inc")) ||
|
||||||
|
!strings.HasPrefix(filepath.Clean(newPath), filepath.Join(self.Root, "inc")) {
|
||||||
return errors.New("You cannot escape!")
|
return errors.New("You cannot escape!")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -249,15 +252,16 @@ func (self *EurekaAdapter) SavePage(oldSlug, newSlug, title, content string) err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *EurekaAdapter) DeletePage(slug string) error {
|
func (self *EurekaAdapter) DeletePage(slug string) error {
|
||||||
if strings.Contains(slug, "../") || strings.Contains(slug, "..\\") {
|
|
||||||
return errors.New("You cannot escape!")
|
|
||||||
}
|
|
||||||
|
|
||||||
siteRoot := self.Config[ConfigOption{
|
siteRoot := self.Config[ConfigOption{
|
||||||
Name: "SITEROOT",
|
Name: "SITEROOT",
|
||||||
Type: "string",
|
Type: "string",
|
||||||
}]
|
}]
|
||||||
htmlFile := filepath.Join(self.Root, siteRoot, slug+"l")
|
htmlFile := filepath.Join(self.Root, siteRoot, slug+"l")
|
||||||
|
|
||||||
|
if !strings.HasPrefix(filepath.Clean(htmlFile), filepath.Join(self.Root, siteRoot)) {
|
||||||
|
return errors.New("You cannot escape!")
|
||||||
|
}
|
||||||
|
|
||||||
_, err := os.Stat(htmlFile)
|
_, err := os.Stat(htmlFile)
|
||||||
if !os.IsNotExist(err) {
|
if !os.IsNotExist(err) {
|
||||||
os.Remove(htmlFile)
|
os.Remove(htmlFile)
|
||||||
|
|
|
@ -54,13 +54,13 @@ func (self *SimpleFileManager) Init(cfg *Config) error {
|
||||||
func (self *SimpleFileManager) ListSubTree(root string) FileListing {
|
func (self *SimpleFileManager) ListSubTree(root string) FileListing {
|
||||||
list := FileListing{}
|
list := FileListing{}
|
||||||
|
|
||||||
if strings.Contains(root, "../") || strings.Contains(root, "..\\") {
|
fullPath := filepath.Join(self.Root, root)
|
||||||
|
|
||||||
|
if !strings.HasPrefix(filepath.Clean(fullPath), self.Root) {
|
||||||
list.Error = "You cannot escape!"
|
list.Error = "You cannot escape!"
|
||||||
return list
|
return list
|
||||||
}
|
}
|
||||||
|
|
||||||
fullPath := filepath.Join(self.Root, root)
|
|
||||||
|
|
||||||
files, err := ioutil.ReadDir(fullPath)
|
files, err := ioutil.ReadDir(fullPath)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -114,7 +114,7 @@ func (self *SimpleFileManager) GetFileData(slug string) FileData {
|
||||||
Error: err.Error(),
|
Error: err.Error(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if !strings.HasPrefix(fullPath, self.Root) {
|
if !strings.HasPrefix(filepath.Clean(fullPath), self.Root) {
|
||||||
return FileData{
|
return FileData{
|
||||||
Error: "You cannot escape!",
|
Error: "You cannot escape!",
|
||||||
}
|
}
|
||||||
|
@ -133,29 +133,31 @@ func (self *SimpleFileManager) GetFileData(slug string) FileData {
|
||||||
|
|
||||||
func (self *SimpleFileManager) Remove(slug string) error {
|
func (self *SimpleFileManager) Remove(slug string) error {
|
||||||
fullPath := filepath.Join(self.Root, slug)
|
fullPath := filepath.Join(self.Root, slug)
|
||||||
_, err := os.Stat(fullPath)
|
|
||||||
|
|
||||||
|
if !strings.HasPrefix(filepath.Clean(fullPath), self.Root) {
|
||||||
|
return errors.New("You cannot escape!")
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err := os.Stat(fullPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if !strings.HasPrefix(fullPath, self.Root) {
|
|
||||||
return errors.New("You cannot escape!")
|
|
||||||
}
|
|
||||||
|
|
||||||
return os.RemoveAll(fullPath)
|
return os.RemoveAll(fullPath)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *SimpleFileManager) AddFile(path string, req *http.Request) error {
|
func (self *SimpleFileManager) AddFile(path string, req *http.Request) error {
|
||||||
fullPath := filepath.Join(self.Root, path)
|
fullPath := filepath.Join(self.Root, path)
|
||||||
|
|
||||||
|
if !strings.HasPrefix(filepath.Clean(fullPath), filepath.Clean(self.Root)) {
|
||||||
|
return errors.New("You cannot escape!")
|
||||||
|
}
|
||||||
|
|
||||||
_, err := os.Stat(fullPath)
|
_, err := os.Stat(fullPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if !strings.HasPrefix(fullPath, filepath.Clean(self.Root)) {
|
|
||||||
return errors.New("You cannot escape!")
|
|
||||||
}
|
|
||||||
|
|
||||||
req.ParseMultipartForm(self.maxUploadMB << 20)
|
req.ParseMultipartForm(self.maxUploadMB << 20)
|
||||||
file, header, err := req.FormFile("file")
|
file, header, err := req.FormFile("file")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -180,7 +182,7 @@ func (self *SimpleFileManager) AddFile(path string, req *http.Request) error {
|
||||||
|
|
||||||
func (self *SimpleFileManager) MkDir(path, newDir string) error {
|
func (self *SimpleFileManager) MkDir(path, newDir string) error {
|
||||||
fullPath := filepath.Join(self.Root, path)
|
fullPath := filepath.Join(self.Root, path)
|
||||||
if !strings.HasPrefix(fullPath, self.Root) {
|
if !strings.HasPrefix(filepath.Clean(fullPath), self.Root) {
|
||||||
return errors.New("You cannot escape!")
|
return errors.New("You cannot escape!")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -204,12 +206,21 @@ func (self *SimpleFileManager) MkDir(path, newDir string) error {
|
||||||
|
|
||||||
func (self *SimpleFileManager) Rename(oldFullPath, newPath, newName string) error {
|
func (self *SimpleFileManager) Rename(oldFullPath, newPath, newName string) error {
|
||||||
fullPath := filepath.Join(self.Root, oldFullPath)
|
fullPath := filepath.Join(self.Root, oldFullPath)
|
||||||
|
|
||||||
|
if !strings.HasPrefix(filepath.Clean(fullPath), self.Root) {
|
||||||
|
return errors.New("You cannot escape!")
|
||||||
|
}
|
||||||
|
|
||||||
_, err := os.Stat(fullPath)
|
_, err := os.Stat(fullPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
newParent := filepath.Join(self.Root, newPath)
|
newParent := filepath.Clean(filepath.Join(self.Root, newPath))
|
||||||
|
if !strings.HasPrefix(newParent, self.Root) {
|
||||||
|
return errors.New("You cannot escape!")
|
||||||
|
}
|
||||||
|
|
||||||
_, err = os.Stat(newParent)
|
_, err = os.Stat(newParent)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -220,6 +231,11 @@ func (self *SimpleFileManager) Rename(oldFullPath, newPath, newName string) erro
|
||||||
newName = oldName
|
newName = oldName
|
||||||
}
|
}
|
||||||
|
|
||||||
|
newFullPath := filepath.Join(newParent, newName)
|
||||||
|
if !strings.HasPrefix(filepath.Clean(newFullPath), newParent) {
|
||||||
|
return errors.New("You cannot escape!")
|
||||||
|
}
|
||||||
|
|
||||||
return os.Rename(fullPath, filepath.Join(newParent, newName))
|
return os.Rename(fullPath, filepath.Join(newParent, newName))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue