Agoric / agoric-sdk

monorepo for the Agoric Javascript smart contract platform
Apache License 2.0
326 stars 206 forks source link

censored error sequence numbers might reveal how many errors were raised by the sending vat #2369

Open warner opened 3 years ago

warner commented 3 years ago

What is the Problem Being Solved?

As @erights was walking us through his logging work today, he showed how an object Alice in vat A could create an Error and send it to object Bob in vat B. The logging system hides the stack trace and other details from other objects in vat A, as well as from vat B and any objects in vat B. Only a privileged outsider can see the hidden data that includes the full stack trace (and other details recorded along with the Error, such as related/causal Errors).

It looked like vat B does learn a terse identifier for the Error, something which includes a sequence number, so that when Bob prints the error to the vat B console, that privileged outsider can see enough data to correlate it with the one that vat A created.

I wanted to investigate whether the exposure of this sequence number to vat B would enable vat B (although not Bob) to learn more about the internal actions of vat A than we would like. In particular, I think vat B would learn the total number of Error that had been created in vat A. If vat B observes two messages that include Errors with a sequence-number gap of N, then it can deduce something about messages which vat A might have sent to vat C or other vats, which should ideally be opaque to it.

There are several tricky tradeoffs here. As a general design rule, the best way to avoid revealing information to someone is to make all your identifiers completely random. This also makes it easiest for an unaugmented (i.e. one not using some sort of log-analysis tools) to look at the log output and match up one side of a conversation with another (using a single counter, which starts at the same value for all instances, is the worst for this, because they all overlap). However to create random identifiers, the code that makes them must have access to a source of random numbers, which is a powerful authority because it enables nondeterminism. We don't give vats access to this, for good reason. You can sort of fake it by using a PRG (pseudo-random generator), which can be as simple as hash(seed, counter), except that you want to provide a different (and unguessable) seed to each vat, which has its own problems, and if you fake it further by passing the same seed to all vats, then all your vats emit the same vaguely-random identifiers, which is probably worse.

The next best way to conceal information is to use a plain counter, but carefully partition your potential observers, and only reveal each counter to a single set of observers. If each receiving vat got Error sequence numbers from a numberspace reserved for it alone, then e.g. vat B would only observe that vat A had sent a certain number of Errors to vat B, and wouldn't learn about the count sent anywhere else. This is troublesome because the easiest way for our privileged outsider to see the correlation is to assign a number when the Error is created, and that scope spans more than one potential observer.

Note that within a single swingset machine, liveslots is the layer that could see this identifier, and liveslots is just as much a part of the TCB as the kernel. So it's not really a big deal to reveal this sequence number to liveslots. However, between swingsets, this identifier will probably show up in the comms protocol, so machine 2 could learn about how many Errors had been serialized by a vat in machine 1, which might include Errors that vat sent to machine 3, which ought to be concealed.

In our majority use case, the vats doing this serialization live on a blockchain, where there are no secrets, so it may not be a high-priority issue. But I'd like to understand what we're revealing accurately, so we can decide whether to try and fix this, or keep it on the list of potential information leaks for the solo case (where the vat and machine have a legitimate expectation of privacy, which this might thwart).

zarutian commented 3 years ago

Hmm... might opaque error identifers via cryptographic hashing help here? I take it that the utility of error identifiers is, for something like Causeway with priviledged info, to reconstitute the order of events, errors, and their causes for debugging or such purposes. If the error or canonical serialized form thereof is cryptographically hashed then I surmise that rather little or no info leakage will ocurr.

warner commented 3 years ago

Yeah, that's basically the PRNG solution. Someone who can learn the seed can reconstruct the sequence number, and find the gaps. But at least the information leakage is bound to leakage of that seed, which is fairly easy to reason about.