Skip to content

Commit

Permalink
fix: Do not allow broken session token by SN
Browse files Browse the repository at this point in the history
If container session token is incorrect, there is no need in Alphabet's check,
the error can be returned immediately to a client; otherwise he has to wait for
the TX to persist infinitely with not feedback. Closes #2466.

Signed-off-by: Pavel Karpy <carpawell@nspcc.ru>
  • Loading branch information
carpawell committed Jan 22, 2024
1 parent c9ddb54 commit 83fb686
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 0 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ Changelog for NeoFS Node
- Created files are not group writable (#2589)
- IR does not create new notary requests for the SN's bootstraps but signs the received ones instead (#2717)
- IR can handle third-party notary requests without reliance on receiving the original one (#2715)
- SN validates container session token's issuer to be container's owner (#2466)

### Removed
- Deprecated `neofs-adm [...] inspect` commands (#2603)
Expand Down
54 changes: 54 additions & 0 deletions pkg/services/container/morph/executor.go
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
package container

import (
"bytes"
"context"
"errors"
"fmt"

"github.com/mr-tron/base58"
"github.com/nspcc-dev/neofs-api-go/v2/container"
"github.com/nspcc-dev/neofs-api-go/v2/refs"
sessionV2 "github.com/nspcc-dev/neofs-api-go/v2/session"
Expand Down Expand Up @@ -80,6 +82,11 @@ func (s *morphExecutor) Put(_ context.Context, tokV2 *sessionV2.Token, body *con
if err != nil {
return nil, fmt.Errorf("invalid session token: %w", err)
}

err = s.validateToken(tokV2, nil, sessionV2.ContainerVerbPut)
if err != nil {
return nil, fmt.Errorf("token validation: %w", err)
}
}

idCnr, err := s.wrt.Put(cnr)
Expand Down Expand Up @@ -120,6 +127,11 @@ func (s *morphExecutor) Delete(_ context.Context, tokV2 *sessionV2.Token, body *
if err != nil {
return nil, fmt.Errorf("invalid session token: %w", err)
}

err = s.validateToken(tokV2, body.GetContainerID(), sessionV2.ContainerVerbDelete)
if err != nil {
return nil, fmt.Errorf("token validation: %w", err)
}
}

var rmWitness containercore.RemovalWitness
Expand Down Expand Up @@ -228,6 +240,11 @@ func (s *morphExecutor) SetExtendedACL(_ context.Context, tokV2 *sessionV2.Token
if err != nil {
return nil, fmt.Errorf("invalid session token: %w", err)
}

err = s.validateToken(tokV2, body.GetEACL().GetContainerID(), sessionV2.ContainerVerbSetEACL)
if err != nil {
return nil, fmt.Errorf("token validation: %w", err)
}
}

err = s.wrt.PutEACL(eaclInfo)
Expand Down Expand Up @@ -274,3 +291,40 @@ func (s *morphExecutor) GetExtendedACL(_ context.Context, body *container.GetExt

return res, nil
}

func (s *morphExecutor) validateToken(t *sessionV2.Token, cID *refs.ContainerID, op sessionV2.ContainerSessionVerb) error {
c := t.GetBody().GetContext()
cc, ok := c.(*sessionV2.ContainerSessionContext)
if !ok {
return errors.New("session is not container related")
}

if sessionCID := cc.ContainerID().GetValue(); !bytes.Equal(sessionCID, cID.GetValue()) {
return fmt.Errorf("wrong container: %s", base58.Encode(sessionCID))
}

if verb := cc.Verb(); verb != op {
return fmt.Errorf("wrong container session operation: %s", verb)
}

if cID == nil { // can be nil for PUT
return nil
}

var cIDSDK cid.ID
err := cIDSDK.ReadFromV2(*cID)
if err != nil {
return fmt.Errorf("cID converting: %w", err)
}

cnr, err := s.rdr.Get(cIDSDK)
if err != nil {
return fmt.Errorf("reading container from the network: %w", err)
}

if issuer := t.GetBody().GetOwnerID().GetValue(); !bytes.Equal(cnr.Value.Owner().WalletBytes(), issuer) {
return fmt.Errorf("session issued not by the owner, issuer: %x", issuer)
}

return nil
}

0 comments on commit 83fb686

Please sign in to comment.