|
|
|
|
@ -218,6 +218,14 @@ func (service *WopiService) PutContent(c *gin.Context, isPutRelative bool) error
|
|
|
|
|
return fmt.Errorf("failed to decode X-WOPI-SuggestedTarget header (UTF-7): %w", err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// X-WOPI-SuggestedTarget is a filename, not a path. Reject any value
|
|
|
|
|
// that could traverse out of the source file's directory.
|
|
|
|
|
if !isValidWopiSuggestedTarget(fileName) {
|
|
|
|
|
c.Status(http.StatusBadRequest)
|
|
|
|
|
c.Header(wopi.InvalidFileNameHeader, "Invalid target file name")
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fileUriParsed, err := fs.NewUriFromString(fileUri)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return fmt.Errorf("failed to parse file uri: %w", err)
|
|
|
|
|
@ -265,6 +273,19 @@ func (service *WopiService) PutContent(c *gin.Context, isPutRelative bool) error
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// isValidWopiSuggestedTarget enforces that X-WOPI-SuggestedTarget is a bare
|
|
|
|
|
// filename (or extension prefixed with ".") and cannot traverse out of the
|
|
|
|
|
// source file's directory once joined onto it.
|
|
|
|
|
func isValidWopiSuggestedTarget(name string) bool {
|
|
|
|
|
if name == "" || name == "." || name == ".." {
|
|
|
|
|
return false
|
|
|
|
|
}
|
|
|
|
|
if strings.ContainsAny(name, "/\\") {
|
|
|
|
|
return false
|
|
|
|
|
}
|
|
|
|
|
return true
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (service *WopiService) GetFile(c *gin.Context) error {
|
|
|
|
|
uri, m, _, viewerSession, dep, err := prepareFs(c)
|
|
|
|
|
if err != nil {
|
|
|
|
|
@ -367,9 +388,9 @@ func (service *WopiService) FileInfo(c *gin.Context) (*WopiFileInfo, error) {
|
|
|
|
|
|
|
|
|
|
type (
|
|
|
|
|
CreateViewerSessionService struct {
|
|
|
|
|
Uri string `json:"uri" form:"uri" binding:"required"`
|
|
|
|
|
Version string `json:"version" form:"version"`
|
|
|
|
|
ViewerID string `json:"viewer_id" form:"viewer_id" binding:"required"`
|
|
|
|
|
Uri string `json:"uri" form:"uri" binding:"required"`
|
|
|
|
|
Version string `json:"version" form:"version"`
|
|
|
|
|
ViewerID string `json:"viewer_id" form:"viewer_id" binding:"required"`
|
|
|
|
|
PreferredAction types.ViewerAction `json:"preferred_action" form:"preferred_action" binding:"required"`
|
|
|
|
|
}
|
|
|
|
|
CreateViewerSessionParamCtx struct{}
|
|
|
|
|
|