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

More Granular Authz perms for cosmwasm contracts #817

Closed
wants to merge 4 commits into from
Closed

More Granular Authz perms for cosmwasm contracts #817

wants to merge 4 commits into from

Conversation

jackzampolin
Copy link
Contributor

No description provided.

@codecov
Copy link

codecov bot commented Apr 27, 2022

Codecov Report

Merging #817 (a6cdeea) into main (23c75b1) will decrease coverage by 0.52%.
The diff coverage is 0.00%.

Impacted file tree graph

@@            Coverage Diff             @@
##             main     #817      +/-   ##
==========================================
- Coverage   59.25%   58.72%   -0.53%     
==========================================
  Files          51       51              
  Lines        5898     5951      +53     
==========================================
  Hits         3495     3495              
- Misses       2150     2203      +53     
  Partials      253      253              
Impacted Files Coverage Δ
x/wasm/types/types.go 40.55% <0.00%> (-13.11%) ⬇️


// MsgTypeURL implements Authorization.MsgTypeURL.
func (a ExecuteContractAuthorization) MsgTypeURL() string {
return "/cosmos.wasm.base.MsgExecuteContract"
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
return "/cosmos.wasm.base.MsgExecuteContract"
return sdk.MsgTypeURL(&MsgExecuteContract{})

should be /cosmwasm.wasm.v1.MsgExecuteContract , ref sendAuthz

// NOTE: exec.Msg is base64 encoded, so we need to decode it first
// If there are allowedMessages then decode the call and check if the message is allowed
callBz := []byte{}
if _, err := base64.RawStdEncoding.Decode(exec.Msg.Bytes(), callBz); err != nil {
Copy link
Contributor

Choose a reason for hiding this comment

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

exec.Msg is json data

Copy link
Member

@webmaster128 webmaster128 left a comment

Choose a reason for hiding this comment

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

Could you extract the whole JSON matching logic into a separate function that can easily be unit tested? Like func isJSONObjectWithTopLevelKey(jsonBytes, allowedKeys).

x/wasm/types/types.go Show resolved Hide resolved
x/wasm/types/types.go Show resolved Hide resolved
@webmaster128
Copy link
Member

I extracted and implemented the JSON object matching in #819 (last commit). I wanted to create a PR into your PR but chan't easily choose your branch as the base branch. Can you check the last commit and cherry-pick it?

@webmaster128
Copy link
Member

webmaster128 commented Apr 27, 2022

With #819 being merged, you can now use IsJSONObjectWithTopLevelKey to match the JSON bytes against a list of allowed top-level keys.

@giansalex
Copy link
Contributor

giansalex commented Apr 27, 2022

A version using IsJSONObjectWithTopLevelKey function.

func (a ExecuteContractAuthorization) Accept(ctx sdk.Context, msg sdk.Msg) (authztypes.AcceptResponse, error) {
	exec, ok := msg.(*MsgExecuteContract)
	if !ok {
		return authztypes.AcceptResponse{}, sdkerrors.ErrInvalidType.Wrap("type mismatch")
	}

	var allowed *AllowedContract
	for _, allowedContract := range a.AllowedContracts {
		// ctx.GasMeter().ConsumeGas(gasCostPerIteration, "wasm execute authorization")
		if allowedContract.ContractAddress == exec.Contract {
			allowed = allowedContract
			break
		}
	}

        // verify contract is allowed
	if allowed == nil {
		return authztypes.AcceptResponse{}, sdkerrors.ErrUnauthorized.Wrapf("cannot run %s contract", exec.Contract)
	}

        // verify msg is allowed
	err := IsJSONObjectWithTopLevelKey(exec.Msg, allowed.AllowedMessages)
	if err != nil {
		return authztypes.AcceptResponse{}, sdkerrors.ErrUnauthorized.Wrapf("no allowed msg: %s", err.Error())
	}

       // remove if is Once
        return authztypes.AcceptResponse{Accept: true, Delete: allowed.Once}, nil
}

are valid duplicate contracts in allowed list?

@giansalex
Copy link
Contributor

giansalex commented Apr 27, 2022

staking authz consumes gas for iterations, in this case it can be applied to contract or msg allowed list.

@webmaster128
Copy link
Member

are valid duplicate contracts in allowed list?

Duplicates are no problem IMO. If you allow a contract twice, well, you still allowed it. But this could be checked in ValidateBasic to point devs to accidental misuse.

staking authz consumes gas for iterations, in this case it can be applied to contract or msg allowed list.

👍 When it comes to payload specific gas consumtion I would definitely start with the size of the JSON document since parsing that JSON is more load than those loops.

@giansalex
Copy link
Contributor

yes, json parsing. I think it might also be necessary to add a command tx wasm grant ....

@alpe alpe added the spike Demo to showcase an idea. label Aug 25, 2022
@ethanfrey
Copy link
Member

This is a great idea.
Work has continued in #966 and #978 and we will use an implementation based on those in the next v0.30 release.

Thank you for pushing it forward with this spike.

@ethanfrey ethanfrey closed this Sep 6, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
spike Demo to showcase an idea.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants