Refuse a node's accounts through any verb, and a stale or service-account agent verdict
The generic command verb ran node account and node agent-account, so an agent could name itself the operator account and have the next send grant it root (hq ADR 0266 review). Refuse every node subcommand but list and show through any verb; refuse the operator account as the agent account in both directions and well-known service accounts as an agent account; and count a verdict heard more than 15 minutes ago as not judged, so stopping the node-engine cannot freeze a healthy one. Re-pin mesh-host to its review head.
This commit is contained in:
@@ -55,6 +55,9 @@ func argvFor(verb string, args map[string]any) ([]string, error) {
|
||||
return nil, err
|
||||
}
|
||||
argv, err := a.commandLine()
|
||||
if err == nil {
|
||||
err = terminalOnly(argv)
|
||||
}
|
||||
if len(a.misread) > 0 {
|
||||
// The table and the command line disagree: the verb reads an argument no caller can see
|
||||
// in its schema, so no caller could ever pass it.
|
||||
@@ -1332,3 +1335,27 @@ func seatAnnouncement(handlers map[string]link.ToolHandler) micro.Info {
|
||||
Endpoints: endpoints,
|
||||
}
|
||||
}
|
||||
|
||||
// nodeReads are the `node` subcommands a verb may run: the ones that only read.
|
||||
var nodeReads = map[string]bool{"list": true, "show": true}
|
||||
|
||||
// terminalOnly refuses, through any verb, a command that is the operator's at the controller's terminal
|
||||
// alone (novox/hq ADR 0266). **Every `node` subcommand that is not a read**: `node account` and
|
||||
// `node agent-account` above all. Whoever may call a verb includes agents, and an agent that named itself
|
||||
// the operator account, or cleared the agent account, would have the next send grant it root through the
|
||||
// sudo module's rule. An allow list, so a subcommand added later is refused until it is judged a read.
|
||||
func terminalOnly(argv []string) error {
|
||||
if len(argv) == 0 || argv[0] != "node" {
|
||||
return nil
|
||||
}
|
||||
if len(argv) > 1 && nodeReads[argv[1]] {
|
||||
return nil
|
||||
}
|
||||
sub := "node"
|
||||
if len(argv) > 1 {
|
||||
sub += " " + argv[1]
|
||||
}
|
||||
return fmt.Errorf("%s is run at the controller's terminal only, never through a verb: a node's accounts "+
|
||||
"decide who may become root on it (novox/hq ADR 0266). A verb may run node list and node show. "+
|
||||
"Nothing was done", sub)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user