Tokens have been in the news a good bit lately. There was the Storm-0558 attack, where the Chinese government attackers were able to forge fake tokens and use them to steal mail. That attack itself was enabled by stealing the tokens belonging to a Microsoft engineer’s corporate account. And then, last week while we were all busy at The Experts Conference, Wiz Security released a new report on another Microsoft security problem. This one was an accidental data breach caused by improper use of something called an Azure shared access signature (SAS). To protect your Azure and Microsoft 365 services, you need to know what tokens are, where they come from, how they can be used, and how to protect them, and this column will hopefully get you pointed in the right direction. 

What’s a Token? 

Simply put, a token is a credential. When you, or an application, wants to log into a resource, the traditional way to do this has been for you to provide a username and password. In legacy Windows, your username and password would be used to generate an access token. Microsoft 365 uses the same basic concept. Microsoft’s documentation goes into a lot of detail that explains what authentication tokens are and how they’re generated. For our purposes, it’s enough to understand this basic flow. 

  1. You ask for a resource.
  1. The application you’re using (a web browser, mobile Outlook, or whatever) sends that request to the service. It doesn’t include an authentication token because you don’t have one yet. 
  1. The resource owner sees that there’s no token, so it asks you to prove your identity.  
  1. The client uses whatever authentication flow the service requires to get your credentials and send them back to the service. This might include MFA or other steps. 
  1. The service examines the credentials. If they’re valid, it generates a signed authentication token and sends it back to your application. 
  1. The application will send the token back with its request and you get whatever access you were originally requesting. 
  1. Each future request to say “look, I was already authenticated”, enabling you to skip all the intermediate steps. 

It is useful, and mostly correct, to think of a token like a membership card: the issuer validates your identity, and then gives you a card that has an expiration date. Presenting the card will get you access to something, and anyone who steals your card might be able to impersonate you. Like a physical membership card, the token is usually stored somewhere (often on disk). 

Token Theft, Replay, and Reuse 

Authentication systems that rely on tokens can be subject to several different types of attacks. Attackers may be able to forge legitimate-seeming tokens; they can steal existing tokens from wherever they’re stored; they can replay a legitimate token that they capture from the network. Then, of course, they can exploit various types of bugs in the token issuing system or the parts of the network that validate tokens and grant access. Finally, users can make mistakes with tokens too, for example by granting them excessive permissions (the root cause of the issue that Wiz reported this week). 

Of these attacks, the most interesting, and serious, ones involve token theft. Since the token is just a block of data that’s stored in RAM or on disk, an attacker who can grab it and exfiltrate it can present it during step 6 of the flow I described earlier and impersonate you. MFA doesn’t help against these attacks because MFA is used to authenticate you to the service so it can issue the token. Presenting your membership card doesn’t usually provoke a second check of your ID, and tokens follow the same pattern. 

What this should point out is that anything that can get filesystem access to a device may be able to steal tokens. Different applications store tokens using different methods. Some encrypt the token before storage, and some do not. For example, the original version of Teams stores unencrypted tokens that an attacker can grab.  

Microsoft, and many other vendors, dismiss this type of token theft by pointing out that if an attacker can get logical access to the filesystem as an authenticated user, the attacker can steal anything they want. This is true, but not especially helpful. So step 1 for protecting against token misuse is to deploy effective physical and anti-malware security measures to keep people from poking around in device filesystems. 

Back in 2021, a clever researcher found an attack path that used cross-site scripting to steal tokens using a malicious Power App in a Teams tab. There are undoubtedly other types of attacks like this out in the wild. Attacks of this type are more difficult to block because they exploit bugs that you may not know about, and there’s really nothing you can add to the existing anti-theft and anti-replay mechanisms that are already built into the Microsoft 365 substrate. 

Not surprisingly, Microsoft has some suggestions on how to protect against token theft attacks, as described in this security playbook, but their efforts are more focused on detecting when these attacks happen rather than on preventing them. 

What about the Azure SAS Token Attack? 

Strictly speaking, the breach that Wiz Security found isn’t an attack. Someone at Microsoft put a bunch of data into an Azure Storage container and created a SAS to allow others to access it, but didn’t realize that they had assigned excessive permissions to the SAS.  

Like the authentication tokens described earlier, a SAS is a signed object (with an optional expiration date) that grants the holder access to the requested resource. Also like an authentication token, the issuer (or the user whose token it is) doesn’t have any way to track who might have a copy of the token. Controlling not only who you distribute SAS tokens to, but also limiting what the SAS grants access to and when it expires, is of critical importance. You can revoke an issued SAS token but that requires rotating the key used to sign it, which may have other undesirable side effects. Wiz Security says “due to the lack of security and governance over Account SAS tokens, they should be considered as sensitive as the account key itself. Therefore, it is highly recommended to avoid using Account SAS for external sharing.” This sounds like a solid recommendation to me, and I’d add to that my recommendation that you check immediately and see if there are any issued account, service, or user delegation SAS tokens issued in your Azure tenants.  

Tokens are Still Better than Naked Passwords 

Based on what I’ve written you might think that tokens themselves are a security risk. The opposite is true: requiring an application to present a signed token to request access means that the underlying username/password (or certificate) aren’t being flung around all over the Internet. This is a big security improvement. It’s difficult to safeguard tokens given that, as a user or admin, you may not know which applications are generating and storing tokens on your behalf or where they are. Hopefully, though, this introduction equips you with a little more knowledge you can use to stay on top of token issuance and use in your applications. 

About the Author

Paul Robichaux

Paul Robichaux, an Office Apps and Services MVP since 2002, works as the senior director of product management at Keepit, spending his time helping to make awesome data protection solutions for the multi-cloud world we’re all living in. Paul's unique background includes stints writing Space Shuttle payload software in FORTRAN, developing cryptographic software for the US National Security Agency, helping giant companies deploy Office 365 to their worldwide users, and writing about and presenting on Microsoft’s software and server products. Paul’s an avid (but slow) triathlete, an instrument-rated private pilot, and an occasional blogger (at http://www.paulrobichaux.com) and Tweeter (@paulrobichaux).

Leave a Reply