We've been talking about this here: https://github.com/golang/go/issues/24160
and here: https://github.com/golang/go/issues/23267 Matt On Thursday, March 15, 2018 at 11:02:08 AM UTC-5, Volker Dobler wrote: > > Importing malicious code will lead to desaster. > > Protecting crypto/rand.Reader somehow from being > tempered with won't help at all. It wouldn't be much > more than cosmetics and feel good security theater. > So why bother? > > V. > > On Monday, 26 February 2018 19:40:48 UTC+1, Fred Akalin wrote: >> >> crypto/rand exposes an io.Reader variable Reader as "a global, shared >> instance of a cryptographically strong pseudo-random generator." >> Furthermore, crypto/rand.Read implicitly uses Reader for its crypto source. >> >> This seems problematic to me because then any package can just overwrite >> crypto/rand.Reader to point to some other object, affecting the security of >> any packages that rely on crypto/rand.Read or crypto/rand.Reader for >> security, e.g. x/crypto/nacl. >> >> One can say that a language can never ultimately defend against code >> running in your same process, but I think it should be possible to write >> something that depends on crypto/rand for security that wouldn't require >> auditing other packages for a single malicious variable write.[1] >> >> I have a proof of concept here: https://github.com/akalin/randtest . The >> main code looks like: >> >> package main >> >> import ( >> "alice/eightball" >> "crypto/rand" >> "fmt" >> ) >> >> func main() { >> eightball.Ask() >> >> var b [32]byte >> rand.Read(b[:]) >> fmt.Printf("%x\n", b) >> } >> >> which prints: >> >> Outlook not so good >> deadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef >> >> and where I half-heartedly attempt to obfuscate the code that actually >> modifies crypto/rand.Reader. I'm sure more clever people can come up with >> more sneaky ways to hide the write.[2] >> >> The main API flaw here, IMO, is that Reader is an io.Reader variable, >> whereas it should be a function that returns an io.Reader. A new API would >> look something like: >> >> // Reader returns an io.Reader that reads from a cryptographically strong >> pseudo-random number generator. >> func Reader() io.Reader >> >> // Read is a helper function that calls Reader() and then passes it to >> io.ReadFull. >> func Read(b []byte) (n int, err error) >> >> Alas, with the Go 1 compatibility guarantee Reader would have to remain, >> and Read would still have to use Reader. But the above could be added as >> new functions, say MakeReader() and SafeRead(). And the standard library >> (and other important external packages like x/crypto/nacl) could be changed >> to use those safe functions. >> >> Unfortunately it seems difficult to mitigate against malicious tampering >> with crypto/rand.Reader. My coworker suggested using reflect to examine its >> underlying type, and assert that it's *crypto/rand.devReader, but that's >> probably the best that can be done. >> >> I'm interested to hear what everyone else thinks, and whether anyone know >> of any particular reason why Reader is exposed like this, before I file a >> bug. Thanks! >> >> -- Fred >> >> [1] Without this flaw, a malicious package would have to use the unsafe >> package to poke around in the internals of crypto/rand, or call out to the >> external OS to e.g. try to redirect access to the random device, which >> seems easier to audit for than a write to crypto/rand.Reader. Of course, >> I'm already assuming that a project worried about this is vendoring all of >> its dependencies. >> >> [2] One nice thing about go is that it's more difficult to write >> underhanded code in than, say, C ( http://www.underhanded-c.org/ ), or >> dynamic languages like Python or Javascript ( >> https://www.nccgroup.trust/us/about-us/newsroom-and-events/blog/2011/august/javascript-cryptography-considered-harmful/ >> >> ) where monkeypatching is easily done. But it seems plausible to me that >> code that modifies crypto/rand.Reader can be snuck into some innocuous >> package that would pass a cursory audit. >> > -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.