mirror of
https://github.com/opencloud-eu/opencloud.git
synced 2026-04-25 09:48:08 -04:00
Merge pull request #9800 from owncloud/collaboration_checkfileid
fix: verify file id in URL matches the one inside the access token
This commit is contained in:
@@ -3,7 +3,6 @@ package connector
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"crypto/sha256"
|
||||
"encoding/base64"
|
||||
"encoding/binary"
|
||||
"encoding/hex"
|
||||
@@ -20,11 +19,11 @@ import (
|
||||
rpcv1beta1 "github.com/cs3org/go-cs3apis/cs3/rpc/v1beta1"
|
||||
providerv1beta1 "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1"
|
||||
typesv1beta1 "github.com/cs3org/go-cs3apis/cs3/types/v1beta1"
|
||||
"github.com/cs3org/reva/v2/pkg/storagespace"
|
||||
"github.com/cs3org/reva/v2/pkg/utils"
|
||||
"github.com/google/uuid"
|
||||
"github.com/owncloud/ocis/v2/services/collaboration/pkg/config"
|
||||
"github.com/owncloud/ocis/v2/services/collaboration/pkg/connector/fileinfo"
|
||||
"github.com/owncloud/ocis/v2/services/collaboration/pkg/helpers"
|
||||
"github.com/owncloud/ocis/v2/services/collaboration/pkg/middleware"
|
||||
"github.com/rs/zerolog"
|
||||
)
|
||||
@@ -1172,10 +1171,7 @@ func (f *FileConnector) generateWOPISrc(ctx context.Context, wopiContext middlew
|
||||
}
|
||||
|
||||
// get the reference
|
||||
resourceId := wopiContext.FileReference.GetResourceId()
|
||||
c := sha256.New()
|
||||
c.Write([]byte(storagespace.FormatResourceID(resourceId)))
|
||||
fileRef := hex.EncodeToString(c.Sum(nil))
|
||||
fileRef := helpers.HashResourceId(wopiContext.FileReference.GetResourceId())
|
||||
|
||||
// generate the URL for the WOPI app to access the new created file
|
||||
wopiSrcURL, err := url.Parse(f.cfg.Wopi.WopiSrc)
|
||||
|
||||
@@ -1,8 +1,13 @@
|
||||
package helpers
|
||||
|
||||
import (
|
||||
"crypto/sha256"
|
||||
"encoding/hex"
|
||||
|
||||
gatewayv1beta1 "github.com/cs3org/go-cs3apis/cs3/gateway/v1beta1"
|
||||
providerv1beta1 "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1"
|
||||
"github.com/cs3org/reva/v2/pkg/rgrpc/todo/pool"
|
||||
"github.com/cs3org/reva/v2/pkg/storagespace"
|
||||
"github.com/owncloud/ocis/v2/services/collaboration/pkg/config"
|
||||
)
|
||||
|
||||
@@ -25,3 +30,11 @@ func GetCS3apiClient(cfg *config.Config, forceNew bool) (gatewayv1beta1.GatewayA
|
||||
}
|
||||
return client, err
|
||||
}
|
||||
|
||||
// HashResourceId builds a urlsafe and stable file reference that can be used for proxy routing,
|
||||
// so that all sessions on one file end on the same office server
|
||||
func HashResourceId(resourceId *providerv1beta1.ResourceId) string {
|
||||
c := sha256.New()
|
||||
c.Write([]byte(storagespace.FormatResourceID(resourceId)))
|
||||
return hex.EncodeToString(c.Sum(nil))
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"regexp"
|
||||
|
||||
appproviderv1beta1 "github.com/cs3org/go-cs3apis/cs3/app/provider/v1beta1"
|
||||
userv1beta1 "github.com/cs3org/go-cs3apis/cs3/identity/user/v1beta1"
|
||||
@@ -12,6 +13,7 @@ import (
|
||||
ctxpkg "github.com/cs3org/reva/v2/pkg/ctx"
|
||||
"github.com/golang-jwt/jwt/v4"
|
||||
"github.com/owncloud/ocis/v2/services/collaboration/pkg/config"
|
||||
"github.com/owncloud/ocis/v2/services/collaboration/pkg/helpers"
|
||||
"github.com/rs/zerolog"
|
||||
"google.golang.org/grpc/metadata"
|
||||
)
|
||||
@@ -45,6 +47,8 @@ type WopiContext struct {
|
||||
// * A contextual zerologger containing information about the request
|
||||
// and the WopiContext
|
||||
func WopiContextAuthMiddleware(cfg *config.Config, next http.Handler) http.Handler {
|
||||
// compile a regexp here to extract the fileid from the URL
|
||||
fileIDregexp := regexp.MustCompile(`^/wopi/files/([0-9a-f]{64})(/.*)?$`)
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
accessToken := r.URL.Query().Get("access_token")
|
||||
if accessToken == "" {
|
||||
@@ -89,7 +93,7 @@ func WopiContextAuthMiddleware(cfg *config.Config, next http.Handler) http.Handl
|
||||
// we might need to check https://learn.microsoft.com/en-us/microsoft-365/cloud-storage-partner-program/rest/common-headers
|
||||
// although some headers might not be sent depending on the client.
|
||||
logger := zerolog.Ctx(ctx)
|
||||
ctx = logger.With().
|
||||
wopiLogger := logger.With().
|
||||
Str("WopiSessionId", r.Header.Get("X-WOPI-SessionId")).
|
||||
Str("WopiOverride", r.Header.Get("X-WOPI-Override")).
|
||||
Str("WopiProof", r.Header.Get("X-WOPI-Proof")).
|
||||
@@ -98,7 +102,16 @@ func WopiContextAuthMiddleware(cfg *config.Config, next http.Handler) http.Handl
|
||||
Str("FileReference", claims.WopiContext.FileReference.String()).
|
||||
Str("ViewMode", claims.WopiContext.ViewMode.String()).
|
||||
Str("Requester", claims.WopiContext.User.GetId().String()).
|
||||
Logger().WithContext(ctx)
|
||||
Logger()
|
||||
ctx = wopiLogger.WithContext(ctx)
|
||||
|
||||
hashedRef := helpers.HashResourceId(claims.WopiContext.FileReference.GetResourceId())
|
||||
matches := fileIDregexp.FindStringSubmatch(r.URL.Path)
|
||||
if len(matches) < 2 || matches[1] != hashedRef {
|
||||
wopiLogger.Error().Msg("file reference in the URL doesn't match the one inside the access token")
|
||||
http.Error(w, http.StatusText(http.StatusUnauthorized), http.StatusUnauthorized)
|
||||
return
|
||||
}
|
||||
|
||||
next.ServeHTTP(w, r.WithContext(ctx))
|
||||
})
|
||||
|
||||
@@ -2,8 +2,6 @@ package service
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/sha256"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"net/url"
|
||||
"path"
|
||||
@@ -19,6 +17,7 @@ import (
|
||||
|
||||
"github.com/owncloud/ocis/v2/ocis-pkg/log"
|
||||
"github.com/owncloud/ocis/v2/services/collaboration/pkg/config"
|
||||
"github.com/owncloud/ocis/v2/services/collaboration/pkg/helpers"
|
||||
"github.com/owncloud/ocis/v2/services/collaboration/pkg/middleware"
|
||||
)
|
||||
|
||||
@@ -83,10 +82,7 @@ func (s *Service) OpenInApp(
|
||||
|
||||
// build a urlsafe and stable file reference that can be used for proxy routing,
|
||||
// so that all sessions on one file end on the same office server
|
||||
|
||||
c := sha256.New()
|
||||
c.Write([]byte(req.GetResourceInfo().GetId().GetStorageId() + "$" + req.GetResourceInfo().GetId().GetSpaceId() + "!" + req.GetResourceInfo().GetId().GetOpaqueId()))
|
||||
fileRef := hex.EncodeToString(c.Sum(nil))
|
||||
fileRef := helpers.HashResourceId(req.GetResourceInfo().GetId())
|
||||
|
||||
// get the file extension to use the right wopi app url
|
||||
fileExt := path.Ext(req.GetResourceInfo().GetPath())
|
||||
|
||||
Reference in New Issue
Block a user