Join GitHub today
GitHub is home to over 28 million developers working together to host and review code, manage projects, and build software together.Sign up
smtp.PlainAuth susceptible to man-in-the-middle password harvesting [Go 1.8] #22134
For obvious reasons, it’s a bad idea to send passwords over plaintext network connections.
RFC 4954 requires that, during SMTP, the PLAIN auth scheme must only be used on network connections secured with TLS. The original implementation of smtp.PlainAuth in Go 1.0 enforced this requirement, and it was documented to do so.
In 2013, issue #5184 was filed objecting to the TLS requirement, despite the fact that it is spelled out clearly in RFC 4954. The only possibly legitimate use case raised was using PLAIN auth for connections to localhost, and the suggested fix was to let the server decide: if it advertises that PLAIN auth is OK, believe it. That approach was adopted in CL 8279043 and released in Go 1.1.
Unfortunately, this is exactly wrong. The whole point of the TLS requirement is to make sure not to send the password to the wrong server or to a man-in-the-middle. Instead of implementing this rule, CL 8279043 blindly trusts the server, so that if a man-in-the-middle says "it's OK, you can send me your password," PlainAuth does. And the documentation was not updated to reflect any of this.
The result is that if you set up a man-in-the-middle SMTP server that doesn’t advertise STARTTLS and does advertise that PLAIN auth is OK, the smtp.PlainAuth implementation would send the username and password.
The fix is to restore the original TLS requirement. As a nod to the localhost use case, we then carve out a documented exception for connections made to localhost (defined as “localhost”, “127.0.0.1”, or “::1”).
Thanks to Stevie Johnstone for reporting this problem.
Update: This has been assigned CVE-2017-15042.