Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: remove create object & bucket approval #225

Merged
merged 23 commits into from
Mar 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 22 additions & 2 deletions client/api_bucket.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import (
"github.com/bnb-chain/greenfield/types/s3util"
permTypes "github.com/bnb-chain/greenfield/x/permission/types"
storageTypes "github.com/bnb-chain/greenfield/x/storage/types"
virtualgroupTypes "github.com/bnb-chain/greenfield/x/virtualgroup/types"

"github.com/bnb-chain/greenfield-go-sdk/pkg/utils"
"github.com/bnb-chain/greenfield-go-sdk/types"
Expand Down Expand Up @@ -163,17 +164,36 @@ func (c *Client) CreateBucket(ctx context.Context, bucketName string, primaryAdd
if err != nil {
return "", err
}
signedMsg, err := c.GetCreateBucketApproval(ctx, createBucketMsg)

accAddress, err := sdk.AccAddressFromHexUnsafe(primaryAddr)
if err != nil {
return "", err
}

sp, err := c.GetStorageProviderInfo(ctx, accAddress)
if err != nil {
return "", err
}

familyID, err := c.QuerySpOptimalGlobalVirtualGroupFamily(ctx, sp.Id, virtualgroupTypes.Strategy_Maximize_Free_Store_Size)
if err != nil {
log.Error().Msg(fmt.Sprintf("failed to query sp ptimal vgf: %s", err.Error()))
var signedMsg *storageTypes.MsgCreateBucket
signedMsg, err = c.GetCreateBucketApproval(ctx, createBucketMsg)
if err != nil {
return "", err
}
familyID = signedMsg.PrimarySpApproval.GlobalVirtualGroupFamilyId
}

createBucketMsg.PrimarySpApproval.GlobalVirtualGroupFamilyId = familyID

// set the default txn broadcast mode as block mode
if opts.TxOpts == nil {
broadcastMode := tx.BroadcastMode_BROADCAST_MODE_SYNC
opts.TxOpts = &gnfdsdk.TxOption{Mode: &broadcastMode}
}
msgs := []sdk.Msg{signedMsg}
msgs := []sdk.Msg{createBucketMsg}

if opts.Tags != nil {
// Set tag
Expand Down
13 changes: 6 additions & 7 deletions client/api_object.go
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,10 @@ func (c *Client) CreateObject(ctx context.Context, bucketName, objectName string
return "", err
}

if !utils.CheckObjectName(objectName) {
return "", fmt.Errorf("fail to check object name:%s", objectName)
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you wrap these format check codes into a single function?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please also move the object name rules into the CheckObjectName function, not comment here.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CheckObjectName already has the same comments, so i just delete it


// compute hash root of payload
expectCheckSums, size, redundancyType, err := c.ComputeHashRoots(reader, opts.IsSerialComputeMode)
if err != nil {
Expand Down Expand Up @@ -148,17 +152,12 @@ func (c *Client) CreateObject(ctx context.Context, bucketName, objectName string
return "", err
}

signedCreateObjectMsg, err := c.GetCreateObjectApproval(ctx, createObjectMsg)
if err != nil {
return "", err
}

// set the default txn broadcast mode as block mode
if opts.TxOpts == nil {
broadcastMode := tx.BroadcastMode_BROADCAST_MODE_SYNC
opts.TxOpts = &gnfdsdk.TxOption{Mode: &broadcastMode}
}
msgs := []sdk.Msg{signedCreateObjectMsg}
msgs := []sdk.Msg{createObjectMsg}

if opts.Tags != nil {
// Set tag
Expand Down Expand Up @@ -1116,7 +1115,7 @@ func (c *Client) ListObjects(ctx context.Context, bucketName string, opts types.
return listObjectsResult, nil
}

// GetCreateObjectApproval returns the signature info for the approval of preCreating resources
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

// Deprecated: GetCreateObjectApproval returns the signature info for the approval of preCreating resources

No need to delete this API

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I mean change the comment to other than delete this line:

// Deprecated: GetCreateObjectApproval returns the signature info for the approval of preCreating resources

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And the same to GetCreateBucketApproval API

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed

// Deprecated: GetCreateObjectApproval returns the signature info for the approval of preCreating resources
func (c *Client) GetCreateObjectApproval(ctx context.Context, createObjectMsg *storageTypes.MsgCreateObject) (*storageTypes.MsgCreateObject, error) {
unsignedBytes := createObjectMsg.GetSignBytes()

Expand Down
62 changes: 62 additions & 0 deletions client/api_virtual_group.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ import (
// IVirtualGroupClient interface defines basic functions related to Virtual Group.
type IVirtualGroupClient interface {
QueryVirtualGroupFamily(ctx context.Context, globalVirtualGroupFamilyID uint32) (*types.GlobalVirtualGroupFamily, error)
QuerySpAvailableGlobalVirtualGroupFamilies(ctx context.Context, spID uint32) ([]uint32, error)
QuerySpOptimalGlobalVirtualGroupFamily(ctx context.Context, spID uint32, strategy types.PickVGFStrategy) (uint32, error)
QueryVirtualGroupParams(ctx context.Context) (*types.Params, error)
}

// QueryVirtualGroupFamily - Query the virtual group family by ID.
Expand All @@ -31,3 +34,62 @@ func (c *Client) QueryVirtualGroupFamily(ctx context.Context, globalVirtualGroup
}
return queryResponse.GlobalVirtualGroupFamily, nil
}

// QuerySpAvailableGlobalVirtualGroupFamilies - Query the virtual group family IDs by SP ID.
//
// Virtual group family(VGF) serve as a means of grouping global virtual groups. Each bucket must be associated with a unique global virtual group family and cannot cross families.
//
// - ctx: Context variables for the current API call.
//
// - spID: Identify the storage provider.
//
// - ret1: The virtual group family detail.
//
// - ret2: Return error when the request failed, otherwise return nil.
func (c *Client) QuerySpAvailableGlobalVirtualGroupFamilies(ctx context.Context, spID uint32) ([]uint32, error) {
queryResponse, err := c.chainClient.QuerySpAvailableGlobalVirtualGroupFamilies(ctx, &types.QuerySPAvailableGlobalVirtualGroupFamiliesRequest{
SpId: spID,
})
if err != nil {
return nil, err
}
return queryResponse.GlobalVirtualGroupFamilyIds, nil
}

// QuerySpOptimalGlobalVirtualGroupFamily - Query the optimal virtual group family ID through SP ID and PickVGFStrategy.
//
// Virtual group family(VGF) serve as a means of grouping global virtual groups. Each bucket must be associated with a unique global virtual group family and cannot cross families.
//
// - ctx: Context variables for the current API call.
//
// - spID: Identify the storage provider.
//
// - ret1: The virtual group family detail.
//
// - ret2: Return error when the request failed, otherwise return nil.
func (c *Client) QuerySpOptimalGlobalVirtualGroupFamily(ctx context.Context, spID uint32, strategy types.PickVGFStrategy) (uint32, error) {
queryResponse, err := c.chainClient.QuerySpOptimalGlobalVirtualGroupFamily(ctx, &types.QuerySpOptimalGlobalVirtualGroupFamilyRequest{
SpId: spID,
})
if err != nil {
return 0, err
}
return queryResponse.GlobalVirtualGroupFamilyId, nil
}

// QueryVirtualGroupParams - Query the virtual group family param.
//
// Virtual group family(VGF) serve as a means of grouping global virtual groups. Each bucket must be associated with a unique global virtual group family and cannot cross families.
//
// - ctx: Context variables for the current API call.
//
// - ret1: Params holds all the parameters of this module..
//
// - ret2: Return error when the request failed, otherwise return nil.
func (c *Client) QueryVirtualGroupParams(ctx context.Context) (*types.Params, error) {
queryResponse, err := c.chainClient.VirtualGroupQueryClient.Params(ctx, &types.QueryParamsRequest{})
if err != nil {
return nil, err
}
return &queryResponse.Params, nil
}
42 changes: 42 additions & 0 deletions pkg/utils/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
"net/url"
"os"
"path/filepath"
"regexp"
"strconv"
"strings"
"unicode/utf8"
Expand Down Expand Up @@ -319,3 +320,44 @@ func ReadFull(r io.Reader, buf []byte) (n int, err error) {
}
return
}

// CheckObjectName This code block checks for unsupported or potentially risky formats in object names.
// The checks are essential for ensuring the security and compatibility of the object names within the system.
// 1. ".." in object names: Checked to prevent path traversal attacks which might access directories outside the intended scope.
// 2. Object name being "/": The root directory should not be used as an object name due to potential security risks and ambiguity.
// 3. "\\" in object names: Backslashes are checked because they are often not supported in UNIX-like file systems and can cause issues in path parsing.
// 4. SQL Injection patterns in object names: Ensures that the object name does not contain patterns that could be used for SQL injection attacks, maintaining the integrity of the database.
func CheckObjectName(objectName string) bool {
if strings.Contains(objectName, "..") ||
objectName == "/" ||
strings.Contains(objectName, "\\") ||
IsSQLInjection(objectName) {
return false
}
return true
}

func IsSQLInjection(input string) bool {
// define patterns that may indicate SQL injection, especially those with a semicolon followed by common SQL keywords
patterns := []string{
"(?i).*;.*select", // Matches any string with a semicolon followed by "select"
"(?i).*;.*insert", // Matches any string with a semicolon followed by "insert"
"(?i).*;.*update", // Matches any string with a semicolon followed by "update"
"(?i).*;.*delete", // Matches any string with a semicolon followed by "delete"
"(?i).*;.*drop", // Matches any string with a semicolon followed by "drop"
"(?i).*;.*alter", // Matches any string with a semicolon followed by "alter"
"/\\*.*\\*/", // Matches SQL block comment
}

for _, pattern := range patterns {
matched, err := regexp.MatchString(pattern, input)
if err != nil {
return false
}
if matched {
return true
}
}

return false
}
Loading