Add docs/design.md; Add sketchy for illustration
This commit is contained in:
parent
df7cd9e670
commit
c368b1062c
|
@ -0,0 +1,96 @@
|
|||
## Design Document
|
||||
|
||||
### Object-Capability Model
|
||||
|
||||
When thinking about security, it's good to start with a specific threat model. Our threat model is the following:
|
||||
|
||||
> We want to assume a thriving ecosystem of Cosmos-SDK modules that are easy to compose into a blockchain application. Some of these modules will be faulty or malicious.
|
||||
|
||||
The Cosmos-SDK is designed to address this threat by being the foundation of an object capability system.
|
||||
|
||||
```
|
||||
The structural properties of object capability systems favor
|
||||
modularity in code design and ensure reliable encapsulation in
|
||||
code implementation.
|
||||
|
||||
These structural properties facilitate the analysis of some
|
||||
security properties of an object-capability program or operating
|
||||
system. Some of these — in particular, information flow properties
|
||||
— can be analyzed at the level of object references and
|
||||
connectivity, independent of any knowledge or analysis of the code
|
||||
that determines the behavior of the objects. As a consequence,
|
||||
these security properties can be established and maintained in the
|
||||
presence of new objects that contain unknown and possibly
|
||||
malicious code.
|
||||
|
||||
These structural properties stem from the two rules governing
|
||||
access to existing objects:
|
||||
|
||||
1) An object A can send a message to B only if object A holds a
|
||||
reference to B.
|
||||
|
||||
2) An object A can obtain a reference to C only
|
||||
if object A receives a message containing a reference to C. As a
|
||||
consequence of these two rules, an object can obtain a reference
|
||||
to another object only through a preexisting chain of references.
|
||||
In short, "Only connectivity begets connectivity."
|
||||
|
||||
- https://en.wikipedia.org/wiki/Object-capability_model
|
||||
```
|
||||
|
||||
Strictly speaking, Golang does not implement object capabilities completely, because of several issues:
|
||||
|
||||
* pervasive ability to import primitive modules (e.g. "unsafe", "os")
|
||||
* pervasive ability to override module vars https://github.com/golang/go/issues/23161
|
||||
* data-race vulnerability where 2+ goroutines can create illegal interface values
|
||||
|
||||
The first is easy to catch by auditing imports and using a proper dependency version control system like Glide. The second and third are unfortunate but it can be audited with some cost.
|
||||
|
||||
Perhaps [Go2 will implement the object capability model](https://github.com/golang/go/issues/23157).
|
||||
|
||||
### What does it look like?
|
||||
|
||||
Only reveal what is necessary to get the work done.
|
||||
|
||||
For example, the following code snippet violates the object capabilities principle:
|
||||
|
||||
```golang
|
||||
type AppAccount struct {...}
|
||||
var account := &AppAccount{
|
||||
Address: pub.Address(),
|
||||
Coins: sdk.Coins{{"ATM", 100}},
|
||||
}
|
||||
var sumValue := externalModule.ComputeSumValue(account)
|
||||
```
|
||||
|
||||
The method "ComputeSumValue" implies a pure function, yet the implied capability of accepting a pointer value is the capability to modify that value. The preferred method signature should take a copy instead.
|
||||
|
||||
```golang
|
||||
var sumValue := externalModule.ComputeSumValue(*account)
|
||||
```
|
||||
|
||||
In the Cosmos SDK, you can see the application of this principle in the basecoin examples folder.
|
||||
|
||||
```golang
|
||||
// File: cosmos-sdk/examples/basecoin/app/init_handlers.go
|
||||
package app
|
||||
|
||||
import (
|
||||
"github.com/cosmos/cosmos-sdk/x/bank"
|
||||
"github.com/cosmos/cosmos-sdk/x/sketchy"
|
||||
)
|
||||
|
||||
func (app *BasecoinApp) initRouterHandlers() {
|
||||
|
||||
// All handlers must be added here.
|
||||
// The order matters.
|
||||
app.router.AddRoute("bank", bank.NewHandler(app.accountMapper))
|
||||
app.router.AddRoute("sketchy", sketchy.NewHandler())
|
||||
}
|
||||
```
|
||||
|
||||
In the Basecoin example, the sketchy handler isn't provided an account mapper, which does provide the bank handler with the capability (in conjunction with the context of a transaction run).
|
||||
|
||||
### More Resources
|
||||
|
||||
* Read the [Cosmos SDK Guide](./guide.md).
|
|
@ -3,6 +3,7 @@ package app
|
|||
import (
|
||||
"github.com/cosmos/cosmos-sdk/x/auth"
|
||||
"github.com/cosmos/cosmos-sdk/x/bank"
|
||||
"github.com/cosmos/cosmos-sdk/x/sketchy"
|
||||
)
|
||||
|
||||
// initCapKeys, initBaseApp, initStores, initHandlers.
|
||||
|
@ -25,4 +26,5 @@ func (app *BasecoinApp) initRouterHandlers() {
|
|||
// All handlers must be added here.
|
||||
// The order matters.
|
||||
app.router.AddRoute("bank", bank.NewHandler(app.accountMapper))
|
||||
app.router.AddRoute("sketchy", sketchy.NewHandler())
|
||||
}
|
||||
|
|
|
@ -131,7 +131,9 @@ const (
|
|||
contextKeyTxBytes
|
||||
)
|
||||
|
||||
// NOTE: Do not expose MultiStore, to require the store key.
|
||||
// NOTE: Do not expose MultiStore.
|
||||
// MultiStore exposes all the keys.
|
||||
// Instead, pass the context and the store key.
|
||||
func (c Context) multiStore() MultiStore {
|
||||
return c.Value(contextKeyMultiStore).(MultiStore)
|
||||
}
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
package sketchy
|
||||
|
||||
import (
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
)
|
||||
|
||||
/*
|
||||
This is just an example to demonstrate a "sketchy" third-party handler module,
|
||||
to demonstrate the "object capability" model for security.
|
||||
|
||||
Since nothing is passed in via arguments to the NewHandler constructor,
|
||||
it cannot affect the handling of other transaction types.
|
||||
*/
|
||||
|
||||
// Handle all "sketchy" type messages.
|
||||
func NewHandler() sdk.Handler {
|
||||
|
||||
return func(ctx sdk.Context, msg sdk.Msg) sdk.Result {
|
||||
// There's nothing accessible from ctx or msg (even using reflection)
|
||||
// that can mutate the state of the application.
|
||||
return sdk.Result{}
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue