AppSec expert Niroshan Rajadurai says putting developers at the center of everything will enable you to meet your security goals.
We recently shipped support for the origin-bound draft standard for security codes delivered via SMS. This standard ensures security codes are entered in a phishing-resistant manner. It accomplishes this by binding an SMS with the sending site’s origin. In addition, the standard defines a format that makes security codes easier for browsers and applications to parse, and removes the need for heuristics to support autofill.
Apple introduced security code autofill in iOS 12. With Text message forwarding enabled, the autofill feature can be used on Safari on macOS Mojave too. This feature is great for user experience:
- Someone with SMS configured on their GitHub account enters their username/password.
- They receive an SMS with their security code and are prompted to fill the code.
- Safari automatically enters the code on the sign in form.
- They click “Submit” and are signed in.
The autofill feature that shipped in iOS 12/macOS Mojave did not use the origin-bound standard. As a result, Apple had to use a number of heuristics to enable autofill. These heuristics left SMS autofill vulnerable to the same kinds of phishing attacks that are used to trick humans.
Let’s quickly walk through how such a phishing attack would traditionally occur before SMS autofill.
- Someone visits https://not-github.example that looks a whole lot like https://github.com.
- They enter their username and password. That username and password is sent to https://not-github.example, which proceeds to enter those credentials into https://github.com (a classic person in the middle attack).
- They are asked to enter the security code just pushed to their device via SMS:
123456 is your GitHub authentication code.
- This person, not realizing they are on a malicious site, proceeds to manually enter the code into https://not-github.example, ultimately giving the security code to the attacker. The attacker enters the code themselves and is now logged in to GitHub.com as the user.
Security code autofill more or less just automated step 4, where the user manually entered the SMS code into https://not-github.example. Heuristics are used to assume that if a text is received and it looks like a security code, the user probably wants that code filled into an input box in the active window on their device. It is not substantially better or worse than manual entry from a phishing perspective.
The core issue with SMS security code phishing is that there was no way to bind the sender of the SMS to the site where it should be used. Apple realized this seemed like a pretty tractable problem with only small changes to the SMS messages sent to users. The origin-bound specification proposes that sites modify their SMS security code messages to include a “footer” where the last line of the message contains, in a standardized format, information about the sending site’s origin as well as the security code itself. For GitHub, our security code message now looks like this:
123456 is your GitHub authentication code. @github.com #123456
This simple addition thwarts phishing attack because the autofill logic can ensure that it only autofills the code on GitHub.com. If the user is currently on https://not-github.example, the browser will refuse to autofill the security code. Technically, this information could also be used by a human entering the code manually as well. However, computers are incredibly adept at following simple rules with near 100% accuracy. Humans on the other hand are incredibly bad at this kind of thing. Research demonstrates that users are confused by URLs. It isn’t their fault; users were forced to deal with URLs to use the Internet, but it is not reasonable to expect those users to have a comprehensive understanding of the subtle security model associated with them.
Before wrapping up, we wanted to address one last related topic. Some folks reading this post might find themselves asking “Why is GitHub talking about, and making additional investment in, SMS as a multi-factor credential? Isn’t SMS broken/insecure/etc?”. It is true that SMS is not impenetrable. SMS is not as resilient as some other options (all of which are supported by GitHub.com) when faced with targeted attacks. However, there is a reason GitHub, as well as a number of other sites with savvy security teams (including Apple), continue to support SMS. The current data supports SMS still being quite effective against the most common attacks.
Security and usability are often in tension with each other. While not as strong as some other multi-factor options, SMS does quite well against the most common attacks and is quite strong on the usability axis: no app to install, can recover from a device dropped in the ocean, etc. GitHub is continually looking at the account security landscape to evaluate where SMS fits and which emerging standards might eventually supplement or even replace it. We are quite excited about the emerging WebAuthn security standard, as it seems to present the rare opportunity to both dramatically improve security while being incredibly easy for everyone (particularly with “platform authenticators” such as Face ID/Touch ID, Windows Hello, etc). However, that standard is still in its infancy. We are following along and looking to see how we can make use of WebAuthn to improve security and usability. In the meantime, we will continue to look for ways we can improve the security of existing options as well. Origin-bound security code SMS delivery was one such improvement that required relatively minimal investment for the security benefit provided.