I met with my colleague Bryan Hughes the other day to discuss the security of a serverless app he's creating for JSConf EU (there will be no spoilers about his creation, don't worry). We had discussed the idea of threat modelling while on a business trip together and he wanted to give it a go. Since I am particularly curious about serverless apps lately thanks to Tal Melamed having dragged me into the OWASP Serverless Top 10 Project, I was excited to have a chance to dive down this rabbit hole.
- Azure Functions App (MSFT serverless)
- JWT tokens for Auth, they will be short lived
- His app will allow other Azure users to call it, with parameters, and it will do something exciting (see? no spoilers!)
Once Bryan has explained what his app would do, he told me his security concerns: who would have access to his app? Could they break into other areas of his Azure Subscription? Exactly what type of authentication token should he use? How would he handle session management? All of which are definitely valid concerns, I was impressed!
We discussed each one of his concerns, and possible technical solutions to mitigate each risk. For instance, use JWTs only to send a random session token value, never a password or sensitive data, and never a number that actually corresponds to something important, such as using someone's SIN number as their session ID number, that is sensitive info, and an insecure direct object reference. I reminded him that JWTs are encoded, not encrypted, and therefore they were not a secure way to transmit data. Also, I suggested that he create a virtual network around this app (firewalls), just in case someone gets into it, it would mean that they can't get into the rest of his network and subscription.
Note: RFC 7516 allows for the encryption of JWT tokens, follow the link for more info.
Then we talked about my concerns, which started with a bunch of questions for Bryan about his users and his data.
- What data are you asking for from your users? Is any of it sensitive?
He's asking for their GitHub info, so that he could give them access to call his serverless app so he could grant them access, but that is all. This one piece of data is sensitive info.
- Who are your users? What are their motivations to use your app?
The users are conference attendees who want to learn how to call a serverless app like an API, and then make his app do the cool thing that it would do. It's a learning opportunity, and it's fun.
- Let's assume you have a malicious user, how could they attack your app?
My first concern was Denial of Service or Brute Force-Style attacks. To avoid these attack vectors he should follow Azure Functions best practices guide, specifically he should set maxConcurrentRequests to a small number (to avoid a distributed denial of service), add throttling (slowing down requests to a reasonable speed, which would stop scripted attacks) by enabling the "dynamicThrottlesEnabled" flag, and ideally also set a low number for the maxOutstandingRequests setting, to ensure no one overflows his buffer for requests, which would also result in a denial of service. (Note this is the "A" in CIA: availability)
Other attacks I was concerned about where someone sending malformed requests, in attempt to elicit unexpected behaviour from his app, such as crashing, deleting or modify data, allowing the user to inject their own code, or other potential issues. We discussed using a white list for user input validation, and rejecting all requests that were not perfectly formed, or that contained any characters that were not "a-z,A-Z,0–9". (Note this is an attack on both Integrity and Availability)
The last attack vector I will list here is that users may attempt to access the data itself, the subscription IDs of all the other users (Confidentiality). This was the most important of the risks in this list, as you are the guardian of this data, and if you lose it, and they were to be attacked successfully as a result, this could cause catastrophic reputation damage (to the conference, to him as the creator of the app, to Microsoft as his employer). When I explained this, it became his #1 priority to ensure his users and their data were protected during and after using his system.
- How long are you keeping this data? Where are you storing it? How are you storing it?
Originally Bryan was hoping to avoid using a database together; no data collection means nothing to steal. Although he's still looking into if that's a possibility, the plan is to use a database, for now.
He decided he would keep the data until just after the conference was over, and then destroy it all (hence making the risk only a 48~ hour risk). It would be stored in a database (we discussed encryption at rest and in transit, as well as always using parameterized queries, and applying least privilege for the DB user that calls those queries (likely read only or read/write, but never DBO).
- What country is this conference in? Will you be subject to GDPR?
It would be in Europe, and therefore is subject to GDPR. I introduced him to Miriam Wiesner, an MSFT employee with a Pentesting and Security Assessment background, who happens to live in the EU and therefore would have familiarity. I said she would have better advice than I would.
The conversation was about an hour, but I think you get the picture.
The key to serverless is remember that almost all the same web app vulnerabilities still apply, such as Injection or Denial of Service (DOS) attacks, and that just because there is no server involved, does not mean you do not need to be diligent about your security of your application.
If you want to keep up with Bryan Hughes, and see the results of his project, you can follow him on Dev.TO.
I hope that you found this informal threat model helpful.