Blue Team Village - Who Dis?
CC Attribution 3.0 Unported:
You are free to use, adapt and copy, distribute and transmit the work or content in adapted or unchanged form for any legal purpose as long as the work is attributed to the author in the manner specified by the author or licensor.
Sudheer, Lak Shmi
In today's ecosystem, verification of identity is no longer applicable just to the user; extending to microservices, cloud providers, IoT devices and many other emerging systems as well. 81% of discovered breaches are due to broken authentication, indicate it as a prevalent issue. Developers are generally aware of different authentication methods used for secure interaction between these entities, but most often lose context on best practices. In this context, we talk about popular authentication schemes like SAML, OAuth, token, magic links, adopted by developers today and emerging ones like WebAuthN. We will present incorrectly coded authentication patterns observed in disclosed reports related to these schemes. Finally, we will conclude with actionable solutions to correct these flaws realized in the form of practical guidelines. These would be security design patterns that developers or designers could refer to in their daily tasks.
 Welcome. Yeah, still waking up. All right, there's a guy that's awake, right? Anybody else? Oh, yeah. Woo, I'm awake. Have a nice day. All right, anyways, we've got, I'm going to try and say these names right. Narayan, Lakshmi and Divya. They are from a large application security team. They're going to be talking about authentication, doing it right, doing it wrong, right? The title of the talk is, who dis, who dis? The right way to authenticate. And without further ado, here you go. Thank you. Hey, good morning everybody and thank you for making it on a Sunday morning. So welcome to our talk, who dis, the right way to authenticate. Who are we? Thank you for the introduction, David. I'm Lakshmi Sudeer. She is Divya and he's Narayan. We do all things application security. We try to be involved in the all stages of SDLC to make sure that we're all in the right way. And we work with and for developers as security engineers, we consider that a primary responsibility. So we work with them to make sure we have secure products that are being shipped out there and we help them with all the security guidelines around whatever they're building. So before we go into the talk itself, just to note that everything we've used for our research is all publicly available data. We haven't used anything that's for a company or anything else as such. Also, one more thing is we want to make this clear out there that we are not encouraging the use of anything that is inherently secure, sorry, insecure. And this is just an attempt that be that if you have to use based on the business case, relatively insecure part of protocol itself, then how do you go about making it secure? So that is what we are trying to address in this talk. It's not to encourage any inherent insecure component of any technology or protocol. Let's dive right into the talk now. Okay. So the agenda for today is we're going to go with the background of like what is authentication and then address like why is this a problem? Of course, that's what leads us to the problem statement. We're going to get more in details about a bunch of protocols and schemes with authentication. Then we're going to drive out a conclusion around, hey, why is this still a problem and what are the patterns we observed across different authorization schemes? Then we want to have some time for like Q and A towards the end as well. So what is authentication? What comes into mind as soon as I say authentication? It could be Kerberos. I think passwords might be the top one. ABIQs, ORTs, SAML and a million of them. Also, something that is closely coupled with authentication is identity. What is identity? Identity is who you are and authentication is what verifies your identity. So authentication is what verifies who you are. Authentication is what actually verifies that I'm Lakshmi Shizhavya and he's Narayan. Now, how do you authenticate? In general, we use passwords, which is pretty common when we log into any application. Or you might have used your pen to go draw some money to gamble a little bit when you're in the conference who doesn't want some fun. And that could be something that you know, a secret that you know that you use to identify yourself to an application saying, hey, it's me who's logging in. Then something else could be UB keys or some device that you own, which is the possession aspect of it. And the other part is where you might have woken up and be like, hey, let me look at my phone and that's your face ID. You might be using a touch ID and that is what you inherently are. So authentication boils down to three things. Something you know that's knowledge, something you have that's possession and something you inherently are. That's inheritance. Now, where does authentication come into play? It might be user authentication broadly and service authentication. With user authentication, I was talking about you logging into an application, drawing out some money and other things that you interact with the system. For example, when we were trying to do this research, we wanted to pull up some of the CVs or some of the bugs that were associated to a bunch of authentication protocols. How did we do that? We logged into an application and this application spoke to multiple applications in the background and those applications reached out to their own data repositories, B2DataBase, B2NestryBucket. And they pulled out all that information, brought it together, provided to the requesting service and this service fed it to a BI tool to make sure we get this readable and ingestible data. And in each of these interactions, each of the service talking to another entity, each of these entities had to authenticate saying, hey, this is me who's requesting and I do have access to this. So when each of these entities were interacting, they had to verify their identity. So in this ecosystem, authentication is mostly a backbone to everything we do today. Now, in this complex ecosystem, we are using authentication. Do you think there's a problem? Of course, yes. And that is why we are on a Sunday morning talking about authentication right here. Now, why is there a problem? Let's look into that more. But if you're a skeptic, we have some data for you. In OAS-Tortem, the latest revision also puts broken authentication in the second place right after code injection. This shouldn't be the case in 2019, is what we thought. Then we pulled up more data and we got this HackerOne report of how much companies are spending on bounties based on the classification of the kind of bugs that are being submitted. And this was surprising to us. I mean, cross-size scripting is expected. Unfortunately, we have that. That's probably for another talk. But broken authentication was still the second most common thing that companies spent a lot of their money on by giving out bounties. And this is where we thought we have OAS. We didn't want to remember passwords. We wanted to keep it complex. We didn't want one pass. I mean, we didn't want to remember passwords for each application, which would make it harder to make it complex. That's how we came up with single sign-on. So there are solutions based on issues we have faced before. But why is this still the second most paid out bounty? So this was mostly the inception for our talk. We were like, this requires some research. What are we doing wrong? What is going wrong with this? So this was mostly where we were like, hey, let's go dig into some of the protocols and see how we can go about this. Now, of course, we looked in deeper. There's been some leakage of tokens. There have been tokens that have been leaked because of some redirect URIs and a bunch of other reports that we actually dived into. There were tokens which weren't expiring at all as well. So we thought we'll come up with an approach and figure out how do we approach this as a holistic problem. So we identified how we went about our approaches. Initially, we identified we went through like the top 200 applications and we were like, hey, let's identify the most commonly used authentication protocols. Then we identified the high-risk issues and we thought let's attack them. Of course, after the research, our idea was to come up with like a remediation or like something that could be pragmatic and useful. And the end goal always, like I said, as security engineers, I feel we hold our responsibility towards helping developers build things securely, implement all those existing protocols securely. So that's how we approach the problem. For today's focus, we're going to start off with JSON web tokens. Then we're going to dig a little deeper into OAuth. Then, of course, the passwordless solutions, that's magic links. And then we're going to talk a little bit about SAML as well. These are the four things we chose to go a little more in depth for the stock. Let's start with JSON web tokens, JOTs or JWTs. What is a JSON web token? A token is nothing but an identifier. With JSON web tokens, it is an encoded JSON blob that has some key value pairs, which is being digitally signed and provided as a token by an authorization server. I know I said a lot of words. So this is where it could be applicable. Let's say as a user, I log into an application using Facebook, Google or any of the social art. There is an authentication server which validates that, hey, this is a username, password, and then it provides a token, a JWT in this case, a JOT. Now, as a user, my identity was verified and this token is given to me as a unique identifier. And now when I want to log into, let's say, Kora as such, I pass this token itself. It validates based on the signature. You could use both symmetric and asymmetric algorithms. So let's say my application has a public key of the authentication server. It validates this token and then if it's validated, saying it wasn't tampered over transit, it actually serves as this user to, like, probably they're requesting to access data. So the user is serviced. Now, why do developers use JOTs in comparison to the session tokens itself, the session IDs, which have, like, a unique random number that was being used? So with JOTs, you achieve authentication because we are relying on the integrity of the token itself and also you could achieve authorization by adding some of the scopes. One more most important key difference is that with a session identifier, you'd have to store these unique random strings along with the user idea or maintain some kind of state every time a request is made. So with JOTs, it's out there, you just service the token only when the token comes in, you validate it based on the digital, you validate the digital signature and you go about servicing it, which makes it stateless. So this is one of the key reasons that most implementations have chosen JOT. Again, it's compact and lightweight. This is a little debatable because it depends on how much information you're putting into the JSON body. And other one is it's scalable compared to session tokens because you're not maintaining all of these unique session IDs and going about servicing as and when they come. So it's pretty scalable. Again, coming back to the point of this is a JSON body, you have key and values. So in situations like OAuth and stuff, you could use this to even exchange information across third parties. So yes, where is it popularly being used? It's being used in OpenID Connect as identity token. It's also being used in OAuth as access tokens and refresh tokens. And JOTs are also being a session, use the session objects. We are going to talk about this being a tricky place to be in a couple of slides. Now that we spoke about JOTs itself, let's look into structure of this JWT. You have on the left side of this is where you see the header payload and signature. This is nothing but an encoded base 64 URL encoded blob. This is what is being passed on to the server. And in the header, when you decode this, so remember that there's no confidentiality since anyone can decode who gets this token. It's just based off integrity. That is validating the digital signature. Now in the header, you see that there is the type of algorithm that was used to create this digital signature. And then you have the type. We are talking about JOT, so that's probably, it's just going to be JOT. In the payload is where you can have all these key value pairs. So that could be like the name of the user, what does the user have access to, or any kind of data. This is a section you mostly use exchange information between third parties or also add like assertions and stuff. So these are called claims for the most part. And then you have the signature which is basically hash and digitally signed such that when an application gets the token, it can validate and make sure that this wasn't tampered with. So we have the header, we have the payload, and we have the signature for a JOT. Let's move on. How many of you here show fans think this is a valid JOT? Okay. Okay. You guys are right. This is unfortunately a valid JOT. One of the things I think you'll notice is we have the header, we have the payload, but the algorithm says none. This is being used in some edge use cases and allowed by the GWT RFC itself. So when the algorithm is none, if you do not validate or handle the library that is actually validating this token, it looks at this algorithm, the algorithm says none. It's supported by the RFC itself, and then it does just regards the signature and goes ahead and services this, validates the token, says it's valid and goes ahead with servicing the request. Now with this, as an attacker, I can go ahead, create any token and every token would be valid. So I can get any actions. I can make any request and get all the information out there. This has been there since 2015, and unfortunately, I mean, again, the JOT RFC has been there from about 2014, I guess, but this has been a problem that is known and still prevalent out there. Now, how do you go about like remediating this problem? One of the things, of course, the best case scenario with programmatic control could be that you might be using a particular algorithm. You could hard code it while validating saying, hey, this is the algorithm that you need to validate every token against. Now, this is the best case scenario. It may not apply in most business cases. That's where comes up the second one where you could whitelist the bunch of algorithms you're using and validate against it saying, hey, the algorithm should match one of these strings, and this is how we service it. So this is how we validate it. So this is one of the approaches you could take. And of course, verifying that the algorithm feel is not none is also a reasonable solution here. What's something else you could do is I think with any software component, anything you're building, choosing the right library holds a huge lot of prominence. JWT.io has more detailed information. So based on your tech stack and what you're using to validate your jobs itself, you could go ahead and make a choice, understand what are the inherent risks, and if it's supposed to none algorithm, you would want to implement that branch where you're like, hey, this is something I need to validate. Now, we are doing this well. We are validating all our tokens for none. And then we are also making sure we're using the right library. What else could go wrong? Let's say we have a user Joe here, and he has access to a mail server. It's valid. He uses an authentication server. He gives us a username password and it validates it presents back the token, the token is valid. Joe puts, sends this token to a mail server, which is the client application. It validates the signature. It's perfect because Joe hasn't done anything malicious so far. It's the right token. Now, what if Joe presents this to another service, which is a finance service, maybe he wants to increase his payroll, get more money. So even this finance service uses the same authentication server, but Joe doesn't have access to go to this finance ops. So in this case, if the client application actually doesn't verify that Joe should not have access, just validating the token was not good enough. But the client applications should also make sure that the user who is actually requesting access does have like access to finance ops in this case. What is the mitigation for this? One of the things you could use alongside Jot itself is a predefined claim called audience where you could put it in the JSON body and say that like you can see here, this was a cool company. So you can say that this user has access only to the user database. That way, when you are a client application that is servicing, that is validating a Jot, you could look for this parameter and be like, hey, this was the issuer. I trust the issuer, but this is the audience. So I am not the audience and I cannot really, I shouldn't be providing access to Joe in this case. Now, we validated, we made sure that the algorithm is right. We made sure we chose the right library. We are also taking care of that user substitution or replay attacks as well. What else is something we should be worried about? If Jots are being used as session objects, you remember I mentioned a couple of slides earlier, then how do you go about logging out? Now, to log out itself, it's a harder problem because Jots, even though they may have a shorter TTL, I mean, again, shorter TTL is debatable, but let's say you have it for two hours. And as a user, I log in, I log out. The token is right out there being valid because we don't have a backend part of it. We just have it's expiry on it, but logging out scenarios need to be handled very carefully. So something you could do for this is have a JTI claim, which is the JWT token identifier itself, which is a unique number, and maintain this unique number on your backend and have like, hey, this is a user. That way, once a user logs out, you could revoke it. The choice was made that it was stateless, but it's no longer stateless anymore because you need to have this revocation list. It's not enough if just your authorization server, the authentication server has this revocation list, but in case of like asymmetric encryption or actually anything you use for digitally signing it, each of these client applications need to also maintain or subscribe to this revocation list itself. Otherwise, while validating the token, I mean, the token would still be valid because it hasn't expired. So revocation has to be handled while it maintains a list, looks for the JTI that is a unique identifier, goes through the list and makes sure that that wasn't revoked. And then goes about like servicing the request. So putting all of this together, some of the key takeaways could be that verify, I couldn't say this enough, validate your algorithm claim, make sure to verify that this is exactly what you use. The second one is, of course, use cryptographically strong algorithms. The third one is around like, hey, utilize all the applicable claims that are already provided in the JWT RFC itself because why not? When the protocol does the heavy lifting for you, why not let it do its job? So make sure to validate that, use those. And I couldn't say this enough that unfortunately, even today revocation is a very common problem we see. So please handle revocation carefully. Make sure that anytime this is used as a session object, think of revocation automatically. So this is about JSON web tokens. Now Divya is going to take up Oauth and talk more about that. Thank you. Okay. Still with us? All right. The next topic is open authentication or open authorization, however you want to call it. So in case you are unfamiliar or if you want a quick primer, Oauth deals with mainly three entities where you have the client, the resource owner, and the authorization server. The client now wants to access some resource and that is provided by the resource owner. And the resource owner needs to authenticate that it's the right client that is accessing the resource. So you have another party, which is the authorization server, which, like, before this traffic flow happens, knows who the client is and can provide that verification information to the resource owner. And the way all these happen is through a bunch of calls, but the main thing that gets exchanged between all these three entities is a bunch of tokens. And there are three kinds of tokens. There is access tokens, refresh tokens, and authorization code, which I'm still going to group it under the token. So what happens if any of them, and especially a client or a web browser on behalf of a client or even a separate service who is acting on behalf of a client is going to be in position of a token, that means they have access to a particular resource that they are trying to access. And this particularly works perfectly when every system follows the best practice possible. And I'm pretty sure all of us are familiar on how likely that is. So I was pretty surprised to see so many verbs, maybe lost, stolen, intercepted, proxied, replayed, and altered. I thought this was excessive, but then I was able to find multiple cases of the tokens being, like, lost, stolen, or intercepted, and this is still not being corrected. And one mitigation that is provided for this for handling tokens properly is to pass it over TLS and have a shorter TTL. And I distinctly remember one person saying to me that the TTL cannot be forever, so anything shorter than that is going to be a shorter TTL, right? So it should be okay. And I've had one person tell me I'm going to keep it at five minutes, so it should be okay. For another person, short is half an hour. For another person, it's six months. For another service, it's going to be one year. So all of this is contextual. And even if it is the shortest case possible, like, are we okay with that open attack window? Not really, right? So what if that's not enough? What if we want to protect the tokens in all situations? Token binding. This is a new concept, and there have been varying opinions on that. So in this presentation, I'm just going to open up. Like, there is a concept of token binding that is available, and also a kind of stop-gap measure that could be applicable in case the full-fledged token binding is not available. So what exactly is token binding? So in a normal OAuth workflow, you have just a token that is being passed between all the entities. In case of token binding, there is some contextual metadata that is attached to it. So in this case, there is a pre-negotiation workflow that happens between the client and the authorization server, where the client provides a key pair, or registers a key pair with the authorization server. So with every subsequent call, the authorization server knows the payload that is coming in, and that's going to contain both the token as well as something attached to it. And the way this happens is during client and server negotiation, there is a payload that is being agreed upon between the client and the server. And this consists of a token binding ID, which could be anything, but the recommendation is that it be between 0 to 255 characters. And the other thing that they negotiate is what signature scheme is going to be used for digitally signing the payload. And this could be the algorithm specified on the slide, and this makes sure that the authorization properly rejects an incorrectly signed payload, because anybody could fake a signature and send it across. More on that later. But there are other metadata that is also available that the client can negotiate with the authorization server, and this could be extensions, binding type, or any other custom payload that you want to add, like a token binding message that only the client and the authorization are waiting off. For the purposes of this presentation and tie-ups with other protocols, I am choosing to focus on the token binding ID and the signature schemes. So what exactly happens? During negotiation, now the client has passed on the key pair and the authorization server has registered it. So in subsequent calls, what happens is, as usual, the TLS handshake happens between the client and the server. There is one additional call that happens, which contains the SEC token binding header that is provided by the client. Now what this contains is the EKMI, which is the exporting key material, and this contains the payload and the message that was agreed upon between the client and the authorization server. Right now, there is API support. Like if you're using Nginx or Apache, you do have this available. You could extend it. There is for Java 8 and 10 as well. I have seen rudimentary applications for Django, but way talent until it becomes official. And as you can see in the workflow, you have the SEC token binding header. And then once the authorization server is ready to communicate or provide or provision the client with the tokens, then it basically attaches or connotates the token binding ID to the refresh token. So for every subsequent message that comes from the client, you not just authenticate or verify the identity of the client just based on the token that was provided, which could be hijacked. But you also depend on another secret that was shared between the client and the authorization server. So some of you may be aware there is no browser support or there's dwindling browser support. So what happens in that case? You could still, the developer could still go ahead and do a mutual TLS transaction. And this is expected in the format of JSON Web Keys. And it happens on a very similar note, except instead of passing you the header, you basically just send across the client's certificate. And then the authorization still has to register it, still has to maintain a separate data store to have this context binding ID. And then with every subsequent call that goes on, you expect, instead of expecting a header or like a connotated token, you would be expecting a token plus the certificate that was already registered. Now, if both the, if you're not taken with token binding and you feel like, oh, there is no enough support for me, then you could definitely look into Pixie, Razor fans, how many of you are familiar with Pixie or heard of it? Awesome. So Pixie is proof of key code exchange. This is available as one of the types of OAuth. This is mainly aimed at mobile and basically workflows where the client's secret storage becomes cumbersome. But if you are looking for a context binding solution, then you could definitely look to Pixie as an alternative. The only way, the only way this differs is the initial negotiation call that goes out. The client provides a code verifier, which is a code challenge, and also provides TM, which is the transformation method. So the authorization server knows a code challenge and how it was derived, and that sets up the platform to expect any code challenge that comes with the subsequent workflows. So as you can see, the client then provides, if, say, for access token request or even subsequently uses the access token, then all it needs to do is send a code verifier along with it. So again, the assumption here is that you have the code verifier, you don't have the access token, or you have the access token, you don't have the code verifier. If you manage to sniff both of them, then the situation is fooba. So you saw a couple of screenshots before, and we saw a couple of open redirect CVEs there. This kind of stood out to me because how simply it was achieved. The way this happened was it was a manipulated redirection URI, and the only unexpected parameter that was passed here was a percentage symbol. The server side wasn't expecting an extra character, so the validation completely failed, but it didn't fail properly. So it still managed to pass on the token to the manipulated redirect URI. And the other thing which went wrong here is passing the redirect URI in the referr header. So how do you exactly mitigate against this? Now, the minimal viable solution here is that you extend your trust boundary to include your client. You are choosing to trust your client that it's going to pass the correct redirect URI in the referr header, and then the server is going to interpret it and pass the token along. Now that is the minimum viable solution here. But if you want to increase your security, but you also want to support providing the access tokens to dynamic URLs, then the other option that is available is to maintain a white list of URLs at the server side. And you expect the client to pass the fully formed URIs, and then you do an exact string matching on a list of URIs rather than one of them. But then the burdens on the developer, like they have to go and maintain the white list, it has to be robust, and all the other things that comes along with that. The best possible solution, which I'm pretty sure will have some pushbacks, is to maintain exactly one URI which is statically registered with the server. You do not pass anything in the referr header, and any time the particular client interacts with the authorization server, because of the registration that happened, the server automatically knows where to send it. So there is a one-time compromise that can happen, and subsequent workflows you're preventing that from being leaked. So that was OAuth, and the two issues were token binding and redirect URI. Moving on for magic links. So what exactly is magic links? You are removing the burden of client secrets, and you expect no passwords. The only thing, the only thing, the only secret that you are generating is a short-lived, hopefully good entropy secret that you are passing along either to the network provider or the email service who have the burden of storing it. And here you depend on, again, short-lived secrets, and you also depend on secure transport for the secret to go from your server to the whoever is handling it. So in case you know somebody who is going to be implementing password lists or is taken by it, make sure that they follow the best practices here, or at least these are based on what I have seen so far. First one is make sure that wherever the secret is being sent, or whichever entity it's being sent to, make sure that the mobile number is verified and make sure that the email is verified. It's laughable how many times that the secret is shared for unverified email or mobile numbers. And the second part is when you are generating a token, make sure that it has sufficient entropy. And like Lakshmi mentioned before, use good authentication protocol, good token generating protocol here, and for example, that is Jot. And even in that, make sure that you specify who it is issued for, and also make sure that you use the right algorithm, even though MD5 is available as an option, please don't head there. The third point is binding the tokens. Again, extending the context binding from Jot or OAuth, make sure that you keep track of where the request to generate a secret is coming from. Make sure that you have a store of whatever secrets you're generating, either in full form or truncated, just make sure you're able to identify it and track it. And also make sure that you're tracking where the responses are coming from. One of the rudimentary checks you could do is that it's coming from two separate devices, or if you don't want to do that, just keep a track of, like, the source where it's coming from or how many times it's coming from. And speaking of how many, make sure that you rate limit the requests that are coming in. Make sure that the secret generation, it's a finite number, if possible, make it singleton, but I know the usability cases where you have to allow it at least like three times or five times. So make sure that you have a rate limit on that because it's super easy to enumerate and just generate the secret and do a phishing attempt yourself. So that's on Magic Links. On to the next topic. Thank you, Divya. The last part of the presentation today would be about SAML, Security Assertion Markup Language. And before we talk about the security issues, the remediations, the mitigations that we can have for developers, I would take this opportunity to set some context on why we decided to talk about SAML and what a SAML. So as you guys are aware, people are moving towards the cloud. And according to recent independent research, application developers on an average use around eight different applications to do the data activities to support ID, HR, payroll systems, and different internal operations as well. So we definitely need an enterprise setup. And that's where a single sign-on comes into play. And what we have seen is that the underlying protocol which powers single sign-on is SAML. And when you use a single sign-on, obviously you are not worried about password reuse or multiple password stores because I mean attackers always try to hit the weakest link in the chain. And you don't have to have multiple password stores and talk about password ashing and how we want to secure those password stores with network isolations as well. And I mean as you guys are aware, IAM is definitely like a challenge. Having good authentication and authorization across the board is a challenge for organizations to come up with. And I have also seen that the vendor support is more like a marketing factor or a marketing metric for single sign-on vendors like Octa, OneLogin, where they try to support this more like a marketing thing that they have where it's easy single sign-on integrations for organizations. And what is SAML? SAML is nothing but an XML data but with multiple digital signatures and assertions to it. And digital signatures are used to verify the authenticity of the service provider and also the authenticity of the identity provider which could be the underlying single sign-on. And SAML also provides authorization on top of authentication. They provide user IDs and metadata which could be like user attributes which can be used by your portal to do like authentication and also like make it as granular as possible based on your context. And if you look at SAML, SAML assertion is usually signed or signed SAML assertion is usually around 7 to 9 kilobytes of data which is pretty verbose for you or for a library to validate and like provide like the right authenticity and provide the right authorization. So let's dive into the security issues that we have seen with SAML and as Divya and Lakshmi already mentioned about having like short TTL, having like an expiration, SAML does have something similar to that. It has something called as not before or not on or after which is basically the timestamp that your portal needs to like validate or like trust or honor a particular SAML assertion which could be infused into the SAML assertion that is signed by the identity provider. And one of the other things is using like a nonce which can prevent deeply based attacks where your portal needs to cache the in response to ID that is part of the SAML request which is again sent back in the SAML response which needs to be checked so that we have more like a nonce that would prevent a replay based attacks where you should not have multiple SAML assertions create or single SAML assertion create multiple sessions. It should be like one SAML assertion creating one particular user session. And SAML is nothing but an XML file of distal signatures so we are also applicable to some XML based issues which could be external references that could be part of your XML file which could lead to like a DDoS attack on our SAML endpoint. For example if you look at this particular diagram where you define an entity and you recursively call this entity multiple times which could like exponentially call it and that could lead to like a billion lofts attack on your SAML endpoint which could bring down your SAML systems in such a way that it would not be available for legit users. And also this could lead to external XML entity attacks where you can have like an XML file or you can have like an internal file like EDCO's name sent to a remote server if you don't have the right mitigations for XSEs which I would be talking in the future slides. And SAML has a lot of distal signatures so I've seen SAML assertions with single distal signatures and multiple distal signatures so missing signatures is an attack that it's more like a fuzzing attack on your SAML endpoint where you remove the distal signatures and see what your portal is handling those kind of SAML responses or SAML messages. And signature wrapping attacks is where you kind of like either clone or move your distal signatures around so that to see if your SAML library or if you're going to do it manually if you have like those code to kind of like catch those exceptions when like you clone signatures with your own public key certificate or you move signatures and assertions around. And one of the recent issues that we saw was about how we parse XML like under the word if you let's say if you're using like a SAML library like PySAML or password SAML it uses like an XML tree to parse the entities, the values, the field values of our XML. And this is where like the canonicalization algorithm comes into play where you can introduce like a comment and the way the XML tree parses it could lead to authorization bypass. So as you see, as you can see, like the left side is where there's an account where it's a fake admin at example.com. But let's say if you can introduce a comment and if the XML tree parser breaks it down into like text and comments, then you can have like an account or like valid credentials for fake admin at example.com. But you can log in as admin and example.com. So this is where like you have to make sure the underlying XML tree parser takes the account of like comments with like canonicalization algorithms. And now let's talk about the mitigations that we have for SAML based security issues. Definitely I've seen that we application developers use a lot of SAML validation libraries like as I already mentioned PySAML, password SAML. So using the right validation library which can catch these exceptions that we spoke about or the security issues and which has been like patched for all the security issues is one of the mitigations that you can have to come up with a good SAML implementation. And also, disabling external entities is very important because when you have like a SAML endpoint, you don't have, I mean in most of the cases you don't need to like have external references because SAML is more like an end cap. So SAML is more like an encapsulated file which has everything to verify the authenticity of a particular identity provider. So you can disable the external entities to be false. So now we are not vulnerable to XSEs on our SAML endpoint. And the other thing is to prevent like a DDoS attack like a billion laughs attack, you need to have some kind of a memory constraints, memory restrictions. That's where you can have like a, you can configure a security manager in your endpoint that will either turn off or limit the entity expansion. So now you have some memory restrictions so that you hit, when you hit a particular memory computation power, then the SAML particular, the particular function is going to like break so that we don't have like a DDoS attack on a SAML endpoint. And it's configured as a security manager is very important to prevent billion laughs attack. And also look at other alternatives. I think the industry is also moving towards OpenID Connect where it's trying to come up with more like a jot after you are a single sign on where it's less verbose, it's easy to interpret and correlate what the metadata of that particular token is rather than looking at a file which is around like 7 to 9 kilobytes. So look at alternatives for a single sign on. So now I think we have covered different authentication patterns and we just wanted to kind of brief on like the commonalities that we have seen across different authentication patterns, let it be jot, OAuth or SAML or pass-by list. So these are some of the things that we would want to brief about which are token metadata. So look at token metadata and token metadata can be used to provide very granular access controls and also like granular authorization for your portal. And the choice of algorithm is very important. Like based on the use case, if secret sharing is easier, then you can like look into a symmetric encryption. If not, then you can look at public encryption. So algorithmic choice is very important as well. And insufficient validation. So any kind of authentication pattern comes with multiple layers of defense where like there are multiple validations in place. So look into like combining validations, not just like just one validation because that could like be programmed incorrectly where we could like lead to like bypass issues or authentication and authorization bypass issues. And missing context is also very important because we have seen that in jobs and as well as in pass-by lists. So you do need to understand the context of your application so that you can decide which authentication approach would be the best for your application. And also understand which kind of encryptions or which kind of algorithms you can use for your applications. And yeah, I mean like just to conclude, I think there are multiple ways to authenticate and we have not touched on like all the different authentication patterns, but we did pick on few and we wanted to talk about them, talk about the bad practices, talk about the mitigations which we have done. And also we have seen that being application security engineers, we also work very close to your developers, educate them, empower them so that they can like securely have like the most secure authentication in place. So yeah, this is what our talk and we are now open for any Q&As. Yes. So do you have any comments on the SSOAWARDS.NET 7th signature bypass that Alvaro Munoz was talking about? Repeat the question. Is the question about like distilled signature bypass or authorization bypass? For only for.NET. For only for.NET. I think we have come across like very common use cases where there was a signature bypass that was reported by Duo Security where like most of the SAML libraries, whether it's OCTA or one log in, where you can like include like a common and like do like a signature bypass. But I don't have any specifics for just for.NET. I can definitely look into that. Okay. Cool. Okay. I'll do that. Thank you. Okay. The question was about how do you prevent token stealing? So I think in JSON Web tokens. Okay. So token could be stolen. I mean, sending over HTTPS is of course, sending over TLS is a pretty good prevention as such. But even if tokens, so I think that's where the other parts of the defense come in. Even if tokens are stolen, you still like can have like some of the things in place where, oh, okay, the problem is with respect to like, that's where I think what she spoke about came into picture, like avoid like leaking tokens through reference or like any of the other headers. So other compensation controls come into place as such because we cannot prevent like, I mean, any kind of token, right? Even whether Jot or not. But one of the things you could do is also not have too much sensitive information inside your JSON key value pair because anyone who sees gets the token can actually view all of the details. So it's mostly compensation controls around any kind of token and that applies to Jots as well. You add a custom check, a custom claim that you're looking for, and it assures you. That's not the standard RFC. The claims, yeah. Using custom parameters? No, like custom claim. Yeah, I mean, we can definitely do that. But since, I mean, as you aware, since a payload is base 64 encoded, like anybody can decode it. So we don't want to put anything that is very sensitive. So one of the things that I've seen is using the JIT. So what we have seen is like, let's say if the JIT, if this particular JIT and if that particular, if there are like a lot of requests with this particular JSON web token, but it has like multiple times the signature was invalid, then we have some kind of like IP racking system to kind of like did it those in places where this particular JOT with this particular JIT is kind of like fuzzing on the digital signature and we want to like identify those. And that's the thing where we kind of like have a pipeline of like identifying those and put it into a central system so that we would say that, okay, these are the bad JITs that are out there. So don't trust them and like probably like work on like global lockout for that. But yeah, I've been to answer your question. We can definitely put like a source IP, like how AWS does for its IM roles. We can definitely do that. But we just that we don't want to put a lot of data like a lot of PII or sensory data into into like a just JSON web tokens because we don't encrypt it. We just send it over TLS or any service can base 64 decoded and like look at that. But yeah, I think we can definitely look into putting a like a source IP doing some IP white listing as well. So if I understood correctly, you wanted recommendations on token binding for mobile apps. So, okay, I did bring it up. So I wanted to include in the presentation, but good that you brought it anyway. So the way it happens is on mobiles, there is like two agents working on it. So if you follow the best practices and keep them separated, the code verifier and the token as they are meant to be the event of compromises lessons. So I wouldn't. How do you start secrets right now? Like if you're using general or for mobile devices, like where do you store them? Yeah, that is correct. Yeah, you could always reverse engineer and get all the secrets that are baked in. But the security that Pixie brings in is that it's two agents kind of communicating and doing the traffic workflow. So even in the event of one compromise, the entire system doesn't get compromised. So I would say just storing both of them in separate apps or separate agents would still give you that security. But eventually all of them would get reversible unless you want to invest on another server where the mobile actually communicates with that. So I would say that it's basically removed from the mobile device entirely. That would be an overkill. Yeah. The dynamic use case with OR, there's always a little bit iffy. So pre-registering always removes that attack vector. So if it is dynamic, then you could definitely do competition controls on the server end. Yeah. If you have other questions, you can definitely reach out to us, but we are out of time. So thank you for being a great audience.
 Welcome. Yeah, still waking up. All right, there's a guy that's awake, right? Anybody else? Oh, yeah. Woo, I'm awake. Have a nice day.  All right, anyways, we've got, I'm going to try and say these names right. Narayan, Lakshmi and Divya. They are from a large application security team. They're going to be talking about authentication, doing it right, doing it wrong, right? The title of the talk is, who dis, who dis? The right way to authenticate. And without further ado, here you go.  Thank you. Hey, good morning everybody and thank you for making it on a Sunday morning. So welcome to our talk, who dis, the right way to authenticate. Who are we? Thank you for the introduction, David. I'm Lakshmi Sudeer. She is Divya and he's Narayan. We do all things application security. We try to be involved in the all stages of SDLC to make sure that we're all in the right way.  And we work with and for developers as security engineers, we consider that a primary responsibility. So we work with them to make sure we have secure products that are being shipped out there and we help them with all the security guidelines around whatever they're building.  So before we go into the talk itself, just to note that everything we've used for our research is all publicly available data. We haven't used anything that's for a company or anything else as such. Also, one more thing is we want to make this clear out there that we are not encouraging the use of anything that is inherently secure, sorry, insecure.  And this is just an attempt that be that if you have to use based on the business case, relatively insecure part of protocol itself, then how do you go about making it secure? So that is what we are trying to address in this talk.  It's not to encourage any inherent insecure component of any technology or protocol. Let's dive right into the talk now.  Okay. So the agenda for today is we're going to go with the background of like what is authentication and then address like why is this a problem? Of course, that's what leads us to the problem statement.  We're going to get more in details about a bunch of protocols and schemes with authentication. Then we're going to drive out a conclusion around, hey, why is this still a problem and what are the patterns we observed across different authorization schemes?  Then we want to have some time for like Q and A towards the end as well. So what is authentication? What comes into mind as soon as I say authentication? It could be Kerberos. I think passwords might be the top one. ABIQs, ORTs, SAML and a million of them.  Also, something that is closely coupled with authentication is identity. What is identity? Identity is who you are and authentication is what verifies your identity. So authentication is what verifies who you are.  Authentication is what actually verifies that I'm Lakshmi Shizhavya and he's Narayan. Now, how do you authenticate? In general, we use passwords, which is pretty common when we log into any application.  Or you might have used your pen to go draw some money to gamble a little bit when you're in the conference who doesn't want some fun.  And that could be something that you know, a secret that you know that you use to identify yourself to an application saying, hey, it's me who's logging in.  Then something else could be UB keys or some device that you own, which is the possession aspect of it. And the other part is where you might have woken up and be like, hey, let me look at my phone and that's your face ID.  You might be using a touch ID and that is what you inherently are. So authentication boils down to three things. Something you know that's knowledge, something you have that's possession and something you inherently are.  That's inheritance. Now, where does authentication come into play? It might be user authentication broadly and service authentication.  With user authentication, I was talking about you logging into an application, drawing out some money and other things that you interact with the system.  For example, when we were trying to do this research, we wanted to pull up some of the CVs or some of the bugs that were associated to a bunch of authentication protocols.  How did we do that? We logged into an application and this application spoke to multiple applications in the background and those applications reached out to their own data repositories, B2DataBase, B2NestryBucket.  And they pulled out all that information, brought it together, provided to the requesting service and this service fed it to a BI tool to make sure we get this readable and ingestible data.  And in each of these interactions, each of the service talking to another entity, each of these entities had to authenticate saying, hey, this is me who's requesting and I do have access to this.  So when each of these entities were interacting, they had to verify their identity.  So in this ecosystem, authentication is mostly a backbone to everything we do today.  Now, in this complex ecosystem, we are using authentication. Do you think there's a problem?  Of course, yes. And that is why we are on a Sunday morning talking about authentication right here.  Now, why is there a problem? Let's look into that more. But if you're a skeptic, we have some data for you.  In OAS-Tortem, the latest revision also puts broken authentication in the second place right after code injection.  This shouldn't be the case in 2019, is what we thought.  Then we pulled up more data and we got this HackerOne report of how much companies are spending on bounties based on the classification of the kind of bugs that are being submitted.  And this was surprising to us. I mean, cross-size scripting is expected. Unfortunately, we have that.  That's probably for another talk. But broken authentication was still the second most common thing that companies spent a lot of their money on by giving out bounties.  And this is where we thought we have OAS. We didn't want to remember passwords. We wanted to keep it complex.  We didn't want one pass. I mean, we didn't want to remember passwords for each application, which would make it harder to make it complex.  That's how we came up with single sign-on. So there are solutions based on issues we have faced before.  But why is this still the second most paid out bounty?  So this was mostly the inception for our talk. We were like, this requires some research. What are we doing wrong?  What is going wrong with this? So this was mostly where we were like, hey, let's go dig into some of the protocols and see how we can go about this.  Now, of course, we looked in deeper. There's been some leakage of tokens.  There have been tokens that have been leaked because of some redirect URIs and a bunch of other reports that we actually dived into.  There were tokens which weren't expiring at all as well. So we thought we'll come up with an approach and figure out how do we approach this as a holistic problem.  So we identified how we went about our approaches. Initially, we identified we went through like the top 200 applications and we were like, hey, let's identify the most commonly used authentication protocols.  Then we identified the high-risk issues and we thought let's attack them. Of course, after the research, our idea was to come up with like a remediation or like something that could be pragmatic and useful.  And the end goal always, like I said, as security engineers, I feel we hold our responsibility towards helping developers build things securely, implement all those existing protocols securely.  So that's how we approach the problem. For today's focus, we're going to start off with JSON web tokens. Then we're going to dig a little deeper into OAuth.  Then, of course, the passwordless solutions, that's magic links. And then we're going to talk a little bit about SAML as well.  These are the four things we chose to go a little more in depth for the stock. Let's start with JSON web tokens, JOTs or JWTs.  What is a JSON web token? A token is nothing but an identifier. With JSON web tokens, it is an encoded JSON blob that has some key value pairs, which is being digitally signed and provided as a token by an authorization server.  I know I said a lot of words. So this is where it could be applicable. Let's say as a user, I log into an application using Facebook, Google or any of the social art.  There is an authentication server which validates that, hey, this is a username, password, and then it provides a token, a JWT in this case, a JOT.  Now, as a user, my identity was verified and this token is given to me as a unique identifier. And now when I want to log into, let's say, Kora as such, I pass this token itself.  It validates based on the signature. You could use both symmetric and asymmetric algorithms. So let's say my application has a public key of the authentication server.  It validates this token and then if it's validated, saying it wasn't tampered over transit, it actually serves as this user to, like, probably they're requesting to access data.  So the user is serviced. Now, why do developers use JOTs in comparison to the session tokens itself, the session IDs, which have, like, a unique random number that was being used?  So with JOTs, you achieve authentication because we are relying on the integrity of the token itself and also you could achieve authorization by adding some of the scopes.  One more most important key difference is that with a session identifier, you'd have to store these unique random strings along with the user idea or maintain some kind of state every time a request is made.  So with JOTs, it's out there, you just service the token only when the token comes in, you validate it based on the digital, you validate the digital signature and you go about servicing it, which makes it stateless.  So this is one of the key reasons that most implementations have chosen JOT. Again, it's compact and lightweight. This is a little debatable because it depends on how much information you're putting into the JSON body.  And other one is it's scalable compared to session tokens because you're not maintaining all of these unique session IDs and going about servicing as and when they come.  So it's pretty scalable. Again, coming back to the point of this is a JSON body, you have key and values. So in situations like OAuth and stuff, you could use this to even exchange information across third parties.  So yes, where is it popularly being used? It's being used in OpenID Connect as identity token. It's also being used in OAuth as access tokens and refresh tokens.  And JOTs are also being a session, use the session objects. We are going to talk about this being a tricky place to be in a couple of slides.  Now that we spoke about JOTs itself, let's look into structure of this JWT. You have on the left side of this is where you see the header payload and signature.  This is nothing but an encoded base 64 URL encoded blob. This is what is being passed on to the server. And in the header, when you decode this, so remember that there's no confidentiality since anyone can decode who gets this token.  It's just based off integrity. That is validating the digital signature. Now in the header, you see that there is the type of algorithm that was used to create this digital signature.  And then you have the type. We are talking about JOT, so that's probably, it's just going to be JOT.  In the payload is where you can have all these key value pairs. So that could be like the name of the user, what does the user have access to, or any kind of data. This is a section you mostly use exchange information between third parties or also add like assertions and stuff.  So these are called claims for the most part. And then you have the signature which is basically hash and digitally signed such that when an application gets the token, it can validate and make sure that this wasn't tampered with.  So we have the header, we have the payload, and we have the signature for a JOT. Let's move on. How many of you here show fans think this is a valid JOT?  Okay. Okay. You guys are right. This is unfortunately a valid JOT. One of the things I think you'll notice is we have the header, we have the payload, but the algorithm says none.  This is being used in some edge use cases and allowed by the GWT RFC itself. So when the algorithm is none, if you do not validate or handle the library that is actually validating this token, it looks at this algorithm, the algorithm says none.  It's supported by the RFC itself, and then it does just regards the signature and goes ahead and services this, validates the token, says it's valid and goes ahead with servicing the request.  Now with this, as an attacker, I can go ahead, create any token and every token would be valid. So I can get any actions. I can make any request and get all the information out there.  This has been there since 2015, and unfortunately, I mean, again, the JOT RFC has been there from about 2014, I guess, but this has been a problem that is known and still prevalent out there.  Now, how do you go about like remediating this problem? One of the things, of course, the best case scenario with programmatic control could be that you might be using a particular algorithm.  You could hard code it while validating saying, hey, this is the algorithm that you need to validate every token against. Now, this is the best case scenario.  It may not apply in most business cases. That's where comes up the second one where you could whitelist the bunch of algorithms you're using and validate against it saying, hey, the algorithm should match one of these strings, and this is how we service it.  So this is how we validate it. So this is one of the approaches you could take. And of course, verifying that the algorithm feel is not none is also a reasonable solution here.  What's something else you could do is I think with any software component, anything you're building, choosing the right library holds a huge lot of prominence.  JWT.io has more detailed information. So based on your tech stack and what you're using to validate your jobs itself, you could go ahead and make a choice, understand what are the inherent risks, and if it's supposed to none algorithm, you would want to implement that branch where you're like, hey, this is something I need to validate.  Now, we are doing this well. We are validating all our tokens for none. And then we are also making sure we're using the right library. What else could go wrong?  Let's say we have a user Joe here, and he has access to a mail server. It's valid. He uses an authentication server. He gives us a username password and it validates it presents back the token, the token is valid.  Joe puts, sends this token to a mail server, which is the client application. It validates the signature. It's perfect because Joe hasn't done anything malicious so far. It's the right token.  Now, what if Joe presents this to another service, which is a finance service, maybe he wants to increase his payroll, get more money. So even this finance service uses the same authentication server, but Joe doesn't have access to go to this finance ops.  So in this case, if the client application actually doesn't verify that Joe should not have access, just validating the token was not good enough. But the client applications should also make sure that the user who is actually requesting access does have like access to finance ops in this case.  What is the mitigation for this? One of the things you could use alongside Jot itself is a predefined claim called audience where you could put it in the JSON body and say that like you can see here, this was a cool company.  So you can say that this user has access only to the user database. That way, when you are a client application that is servicing, that is validating a Jot, you could look for this parameter and be like, hey, this was the issuer. I trust the issuer, but this is the audience. So I am not the audience and I cannot really, I shouldn't be providing access to Joe in this case.  Now, we validated, we made sure that the algorithm is right. We made sure we chose the right library. We are also taking care of that user substitution or replay attacks as well. What else is something we should be worried about?  If Jots are being used as session objects, you remember I mentioned a couple of slides earlier, then how do you go about logging out?  Now, to log out itself, it's a harder problem because Jots, even though they may have a shorter TTL, I mean, again, shorter TTL is debatable, but let's say you have it for two hours.  And as a user, I log in, I log out. The token is right out there being valid because we don't have a backend part of it. We just have it's expiry on it, but logging out scenarios need to be handled very carefully.  So something you could do for this is have a JTI claim, which is the JWT token identifier itself, which is a unique number, and maintain this unique number on your backend and have like, hey, this is a user.  That way, once a user logs out, you could revoke it. The choice was made that it was stateless, but it's no longer stateless anymore because you need to have this revocation list.  It's not enough if just your authorization server, the authentication server has this revocation list, but in case of like asymmetric encryption or actually anything you use for digitally signing it, each of these client applications need to also maintain or subscribe to this revocation list itself.  Otherwise, while validating the token, I mean, the token would still be valid because it hasn't expired. So revocation has to be handled while it maintains a list, looks for the JTI that is a unique identifier, goes through the list and makes sure that that wasn't revoked.  And then goes about like servicing the request. So putting all of this together, some of the key takeaways could be that verify, I couldn't say this enough, validate your algorithm claim, make sure to verify that this is exactly what you use.  The second one is, of course, use cryptographically strong algorithms. The third one is around like, hey, utilize all the applicable claims that are already provided in the JWT RFC itself because why not?  When the protocol does the heavy lifting for you, why not let it do its job? So make sure to validate that, use those. And I couldn't say this enough that unfortunately, even today revocation is a very common problem we see.  So please handle revocation carefully. Make sure that anytime this is used as a session object, think of revocation automatically. So this is about JSON web tokens. Now Divya is going to take up Oauth and talk more about that. Thank you.  Okay. Still with us? All right. The next topic is open authentication or open authorization, however you want to call it. So in case you are unfamiliar or if you want a quick primer, Oauth deals with mainly three entities where you have the client, the resource owner, and the authorization server.  The client now wants to access some resource and that is provided by the resource owner. And the resource owner needs to authenticate that it's the right client that is accessing the resource. So you have another party, which is the authorization server, which, like, before this traffic flow happens, knows who the client is and can provide that verification information to the resource owner.  And the way all these happen is through a bunch of calls, but the main thing that gets exchanged between all these three entities is a bunch of tokens. And there are three kinds of tokens. There is access tokens, refresh tokens, and authorization code, which I'm still going to group it under the token.  So what happens if any of them, and especially a client or a web browser on behalf of a client or even a separate service who is acting on behalf of a client is going to be in position of a token, that means they have access to a particular resource that they are trying to access.  And this particularly works perfectly when every system follows the best practice possible. And I'm pretty sure all of us are familiar on how likely that is. So I was pretty surprised to see so many verbs, maybe lost, stolen, intercepted, proxied, replayed, and altered.  I thought this was excessive, but then I was able to find multiple cases of the tokens being, like, lost, stolen, or intercepted, and this is still not being corrected.  And one mitigation that is provided for this for handling tokens properly is to pass it over TLS and have a shorter TTL.  And I distinctly remember one person saying to me that the TTL cannot be forever, so anything shorter than that is going to be a shorter TTL, right? So it should be okay.  And I've had one person tell me I'm going to keep it at five minutes, so it should be okay. For another person, short is half an hour. For another person, it's six months.  For another service, it's going to be one year. So all of this is contextual. And even if it is the shortest case possible, like, are we okay with that open attack window? Not really, right?  So what if that's not enough? What if we want to protect the tokens in all situations?  Token binding. This is a new concept, and there have been varying opinions on that.  So in this presentation, I'm just going to open up. Like, there is a concept of token binding that is available, and also a kind of stop-gap measure that could be applicable in case the full-fledged token binding is not available.  So what exactly is token binding? So in a normal OAuth workflow, you have just a token that is being passed between all the entities.  In case of token binding, there is some contextual metadata that is attached to it. So in this case, there is a pre-negotiation workflow that happens between the client and the authorization server, where the client provides a key pair, or registers a key pair with the authorization server.  So with every subsequent call, the authorization server knows the payload that is coming in, and that's going to contain both the token as well as something attached to it.  And the way this happens is during client and server negotiation, there is a payload that is being agreed upon between the client and the server.  And this consists of a token binding ID, which could be anything, but the recommendation is that it be between 0 to 255 characters.  And the other thing that they negotiate is what signature scheme is going to be used for digitally signing the payload.  And this could be the algorithm specified on the slide, and this makes sure that the authorization properly rejects an incorrectly signed payload,  because anybody could fake a signature and send it across. More on that later.  But there are other metadata that is also available that the client can negotiate with the authorization server, and this could be extensions, binding type, or any other custom payload that you want to add,  like a token binding message that only the client and the authorization are waiting off.  For the purposes of this presentation and tie-ups with other protocols, I am choosing to focus on the token binding ID and the signature schemes.  So what exactly happens? During negotiation, now the client has passed on the key pair and the authorization server has registered it.  So in subsequent calls, what happens is, as usual, the TLS handshake happens between the client and the server.  There is one additional call that happens, which contains the SEC token binding header that is provided by the client.  Now what this contains is the EKMI, which is the exporting key material, and this contains the payload and the message that was agreed upon between the client and the authorization server.  Right now, there is API support. Like if you're using Nginx or Apache, you do have this available. You could extend it.  There is for Java 8 and 10 as well. I have seen rudimentary applications for Django, but way talent until it becomes official.  And as you can see in the workflow, you have the SEC token binding header.  And then once the authorization server is ready to communicate or provide or provision the client with the tokens, then it basically attaches or connotates the token binding ID to the refresh token.  So for every subsequent message that comes from the client, you not just authenticate or verify the identity of the client just based on the token that was provided, which could be hijacked.  But you also depend on another secret that was shared between the client and the authorization server.  So some of you may be aware there is no browser support or there's dwindling browser support. So what happens in that case?  You could still, the developer could still go ahead and do a mutual TLS transaction.  And this is expected in the format of JSON Web Keys.  And it happens on a very similar note, except instead of passing you the header, you basically just send across the client's certificate.  And then the authorization still has to register it, still has to maintain a separate data store to have this context binding ID.  And then with every subsequent call that goes on, you expect, instead of expecting a header or like a connotated token, you would be expecting a token plus the certificate that was already registered.  Now, if both the, if you're not taken with token binding and you feel like, oh, there is no enough support for me, then you could definitely look into Pixie,  Razor fans, how many of you are familiar with Pixie or heard of it?  Awesome. So Pixie is proof of key code exchange. This is available as one of the types of OAuth.  This is mainly aimed at mobile and basically workflows where the client's secret storage becomes cumbersome.  But if you are looking for a context binding solution, then you could definitely look to Pixie as an alternative.  The only way, the only way this differs is the initial negotiation call that goes out.  The client provides a code verifier, which is a code challenge, and also provides TM, which is the transformation method.  So the authorization server knows a code challenge and how it was derived, and that sets up the platform to expect any code challenge that comes with the subsequent workflows.  So as you can see, the client then provides, if, say, for access token request or even subsequently uses the access token, then all it needs to do is send a code verifier along with it.  So again, the assumption here is that you have the code verifier, you don't have the access token, or you have the access token, you don't have the code verifier.  If you manage to sniff both of them, then the situation is fooba.  So you saw a couple of screenshots before, and we saw a couple of open redirect CVEs there.  This kind of stood out to me because how simply it was achieved.  The way this happened was it was a manipulated redirection URI, and the only unexpected parameter that was passed here was a percentage symbol.  The server side wasn't expecting an extra character, so the validation completely failed, but it didn't fail properly.  So it still managed to pass on the token to the manipulated redirect URI.  And the other thing which went wrong here is passing the redirect URI in the referr header.  So how do you exactly mitigate against this?  Now, the minimal viable solution here is that you extend your trust boundary to include your client.  You are choosing to trust your client that it's going to pass the correct redirect URI in the referr header, and then the server is going to interpret it and pass the token along.  Now that is the minimum viable solution here.  But if you want to increase your security, but you also want to support providing the access tokens to dynamic URLs, then the other option that is available is to maintain a white list of URLs at the server side.  And you expect the client to pass the fully formed URIs, and then you do an exact string matching on a list of URIs rather than one of them.  But then the burdens on the developer, like they have to go and maintain the white list, it has to be robust, and all the other things that comes along with that.  The best possible solution, which I'm pretty sure will have some pushbacks, is to maintain exactly one URI which is statically registered with the server.  You do not pass anything in the referr header, and any time the particular client interacts with the authorization server, because of the registration that happened, the server automatically knows where to send it.  So there is a one-time compromise that can happen, and subsequent workflows you're preventing that from being leaked.  So that was OAuth, and the two issues were token binding and redirect URI.  Moving on for magic links.  So what exactly is magic links?  You are removing the burden of client secrets, and you expect no passwords.  The only thing, the only thing, the only secret that you are generating is a short-lived, hopefully good entropy secret that you are passing along either to the network provider or the email service who have the burden of storing it.  And here you depend on, again, short-lived secrets, and you also depend on secure transport for the secret to go from your server to the whoever is handling it.  So in case you know somebody who is going to be implementing password lists or is taken by it, make sure that they follow the best practices here, or at least these are based on what I have seen so far.  First one is make sure that wherever the secret is being sent, or whichever entity it's being sent to, make sure that the mobile number is verified and make sure that the email is verified.  It's laughable how many times that the secret is shared for unverified email or mobile numbers.  And the second part is when you are generating a token, make sure that it has sufficient entropy.  And like Lakshmi mentioned before, use good authentication protocol, good token generating protocol here, and for example, that is Jot.  And even in that, make sure that you specify who it is issued for, and also make sure that you use the right algorithm, even though MD5 is available as an option, please don't head there.  The third point is binding the tokens.  Again, extending the context binding from Jot or OAuth, make sure that you keep track of where the request to generate a secret is coming from.  Make sure that you have a store of whatever secrets you're generating, either in full form or truncated, just make sure you're able to identify it and track it.  And also make sure that you're tracking where the responses are coming from.  One of the rudimentary checks you could do is that it's coming from two separate devices, or if you don't want to do that, just keep a track of, like, the source where it's coming from or how many times it's coming from.  And speaking of how many, make sure that you rate limit the requests that are coming in.  Make sure that the secret generation, it's a finite number, if possible, make it singleton, but I know the usability cases where you have to allow it at least like three times or five times.  So make sure that you have a rate limit on that because it's super easy to enumerate and just generate the secret and do a phishing attempt yourself.  So that's on Magic Links.  On to the next topic.  Thank you, Divya.  The last part of the presentation today would be about SAML, Security Assertion Markup Language.  And before we talk about the security issues, the remediations, the mitigations that we can have for developers, I would take this opportunity to set some context on why we decided to talk about SAML and what a SAML.  So as you guys are aware, people are moving towards the cloud.  And according to recent independent research, application developers on an average use around eight different applications to do the data activities to support ID, HR, payroll systems, and different internal operations as well.  So we definitely need an enterprise setup.  And that's where a single sign-on comes into play.  And what we have seen is that the underlying protocol which powers single sign-on is SAML.  And when you use a single sign-on, obviously you are not worried about password reuse or multiple password stores because I mean attackers always try to hit the weakest link in the chain.  And you don't have to have multiple password stores and talk about password ashing and how we want to secure those password stores with network isolations as well.  And I mean as you guys are aware, IAM is definitely like a challenge. Having good authentication and authorization across the board is a challenge for organizations to come up with.  And I have also seen that the vendor support is more like a marketing factor or a marketing metric for single sign-on vendors like Octa, OneLogin, where they try to support this more like a marketing thing that they have where it's easy single sign-on integrations for organizations.  And what is SAML? SAML is nothing but an XML data but with multiple digital signatures and assertions to it.  And digital signatures are used to verify the authenticity of the service provider and also the authenticity of the identity provider which could be the underlying single sign-on.  And SAML also provides authorization on top of authentication. They provide user IDs and metadata which could be like user attributes which can be used by your portal to do like authentication and also like make it as granular as possible based on your context.  And if you look at SAML, SAML assertion is usually signed or signed SAML assertion is usually around 7 to 9 kilobytes of data which is pretty verbose for you or for a library to validate and like provide like the right authenticity and provide the right authorization.  So let's dive into the security issues that we have seen with SAML and as Divya and Lakshmi already mentioned about having like short TTL, having like an expiration, SAML does have something similar to that.  It has something called as not before or not on or after which is basically the timestamp that your portal needs to like validate or like trust or honor a particular SAML assertion which could be infused into the SAML assertion that is signed by the identity provider.  And one of the other things is using like a nonce which can prevent deeply based attacks where your portal needs to cache the in response to ID that is part of the SAML request which is again sent back in the SAML response which needs to be checked so that we have more like a nonce that would prevent a replay  based attacks where you should not have multiple SAML assertions create or single SAML assertion create multiple sessions. It should be like one SAML assertion creating one particular user session.  And SAML is nothing but an XML file of distal signatures so we are also applicable to some XML based issues which could be external references that could be part of your XML file which could lead to like a DDoS attack on our SAML endpoint.  For example if you look at this particular diagram where you define an entity and you recursively call this entity multiple times which could like exponentially call it and that could lead to like a billion lofts attack on your SAML endpoint which could bring down your SAML systems in such a way that it would not be available for legit users.  And also this could lead to external XML entity attacks where you can have like an XML file or you can have like an internal file like EDCO's name sent to a remote server if you don't have the right mitigations for XSEs which I would be talking in the future slides.  And SAML has a lot of distal signatures so I've seen SAML assertions with single distal signatures and multiple distal signatures so missing signatures is an attack that it's more like a fuzzing attack on your SAML endpoint where you remove the distal signatures and see what your portal is handling those kind of SAML responses or SAML messages.  And signature wrapping attacks is where you kind of like either clone or move your distal signatures around so that to see if your SAML library or if you're going to do it manually if you have like those code to kind of like catch those exceptions when like you clone signatures with your own public key certificate or you move signatures and assertions around.  And one of the recent issues that we saw was about how we parse XML like under the word if you let's say if you're using like a SAML library like PySAML or password SAML it uses like an XML tree to parse the entities, the values, the field values of our XML.  And this is where like the canonicalization algorithm comes into play where you can introduce like a comment and the way the XML tree parses it could lead to authorization bypass.  So as you see, as you can see, like the left side is where there's an account where it's a fake admin at example.com.  But let's say if you can introduce a comment and if the XML tree parser breaks it down into like text and comments, then you can have like an account or like valid credentials for fake admin at example.com.  But you can log in as admin and example.com.  So this is where like you have to make sure the underlying XML tree parser takes the account of like comments with like canonicalization algorithms.  And now let's talk about the mitigations that we have for SAML based security issues.  Definitely I've seen that we application developers use a lot of SAML validation libraries like as I already mentioned PySAML, password SAML.  So using the right validation library which can catch these exceptions that we spoke about or the security issues and which has been like patched for all the security issues is one of the mitigations that you can have to come up with a good SAML implementation.  And also, disabling external entities is very important because when you have like a SAML endpoint, you don't have, I mean in most of the cases you don't need to like have external references because SAML is more like an end cap.  So SAML is more like an encapsulated file which has everything to verify the authenticity of a particular identity provider.  So you can disable the external entities to be false.  So now we are not vulnerable to XSEs on our SAML endpoint.  And the other thing is to prevent like a DDoS attack like a billion laughs attack, you need to have some kind of a memory constraints, memory restrictions.  That's where you can have like a, you can configure a security manager in your endpoint that will either turn off or limit the entity expansion.  So now you have some memory restrictions so that you hit, when you hit a particular memory computation power, then the SAML particular, the particular function is going to like break so that we don't have like a DDoS attack on a SAML endpoint.  And it's configured as a security manager is very important to prevent billion laughs attack.  And also look at other alternatives. I think the industry is also moving towards OpenID Connect where it's trying to come up with more like a jot after you are a single sign on where it's less verbose, it's easy to interpret and correlate what the metadata of that particular token is rather than looking at a file which is around like 7 to 9 kilobytes.  So look at alternatives for a single sign on.  So now I think we have covered different authentication patterns and we just wanted to kind of brief on like the commonalities that we have seen across different authentication patterns, let it be jot, OAuth or SAML or pass-by list.  So these are some of the things that we would want to brief about which are token metadata.  So look at token metadata and token metadata can be used to provide very granular access controls and also like granular authorization for your portal.  And the choice of algorithm is very important. Like based on the use case, if secret sharing is easier, then you can like look into a symmetric encryption.  If not, then you can look at public encryption. So algorithmic choice is very important as well.  And insufficient validation. So any kind of authentication pattern comes with multiple layers of defense where like there are multiple validations in place.  So look into like combining validations, not just like just one validation because that could like be programmed incorrectly where we could like lead to like bypass issues or authentication and authorization bypass issues.  And missing context is also very important because we have seen that in jobs and as well as in pass-by lists.  So you do need to understand the context of your application so that you can decide which authentication approach would be the best for your application.  And also understand which kind of encryptions or which kind of algorithms you can use for your applications.  And yeah, I mean like just to conclude, I think there are multiple ways to authenticate and we have not touched on like all the different authentication patterns,  but we did pick on few and we wanted to talk about them, talk about the bad practices, talk about the mitigations which we have done.  And also we have seen that being application security engineers, we also work very close to your developers, educate them, empower them so that they can like securely have like the most secure authentication in place.  So yeah, this is what our talk and we are now open for any Q&As.  Yes.  So do you have any comments on the SSOAWARDS.NET 7th signature bypass that Alvaro Munoz was talking about?  Repeat the question.  Is the question about like distilled signature bypass or authorization bypass?  For only for.NET.  For only for.NET.  I think we have come across like very common use cases where there was a signature bypass that was reported by Duo Security where like most of the SAML libraries,  whether it's OCTA or one log in, where you can like include like a common and like do like a signature bypass.  But I don't have any specifics for just for.NET. I can definitely look into that.  Okay.  Cool. Okay. I'll do that. Thank you.  Okay. The question was about how do you prevent token stealing?  So I think in JSON Web tokens.  Okay. So token could be stolen. I mean, sending over HTTPS is of course, sending over TLS is a pretty good prevention as such.  But even if tokens, so I think that's where the other parts of the defense come in.  Even if tokens are stolen, you still like can have like some of the things in place where, oh, okay, the problem is with respect to like,  that's where I think what she spoke about came into picture, like avoid like leaking tokens through reference or like any of the other headers.  So other compensation controls come into place as such because we cannot prevent like, I mean, any kind of token, right?  Even whether Jot or not. But one of the things you could do is also not have too much sensitive information inside your JSON key value pair because anyone who sees gets the token can actually view all of the details.  So it's mostly compensation controls around any kind of token and that applies to Jots as well.  You add a custom check, a custom claim that you're looking for, and it assures you.  That's not the standard RFC.  The claims, yeah.  Using custom parameters?  No, like custom claim.  Yeah, I mean, we can definitely do that.  But since, I mean, as you aware, since a payload is base 64 encoded, like anybody can decode it.  So we don't want to put anything that is very sensitive.  So one of the things that I've seen is using the JIT.  So what we have seen is like, let's say if the JIT, if this particular JIT and if that particular, if there are like a lot of requests with this particular JSON web token,  but it has like multiple times the signature was invalid, then we have some kind of like IP racking system to kind of like did it those in places where this particular JOT with this particular JIT is kind of like fuzzing on the digital signature and we want to like identify those.  And that's the thing where we kind of like have a pipeline of like identifying those and put it into a central system so that we would say that, okay, these are the bad JITs that are out there.  So don't trust them and like probably like work on like global lockout for that.  But yeah, I've been to answer your question. We can definitely put like a source IP, like how AWS does for its IM roles.  We can definitely do that. But we just that we don't want to put a lot of data like a lot of PII or sensory data into into like a just JSON web tokens because we don't encrypt it.  We just send it over TLS or any service can base 64 decoded and like look at that.  But yeah, I think we can definitely look into putting a like a source IP doing some IP white listing as well.  So if I understood correctly, you wanted recommendations on token binding for mobile apps.  So, okay, I did bring it up. So I wanted to include in the presentation, but good that you brought it anyway. So the way it happens is on mobiles, there is like two agents working on it.  So if you follow the best practices and keep them separated, the code verifier and the token as they are meant to be the event of compromises lessons.  So I wouldn't. How do you start secrets right now? Like if you're using general or for mobile devices, like where do you store them?  Yeah, that is correct. Yeah, you could always reverse engineer and get all the secrets that are baked in.  But the security that Pixie brings in is that it's two agents kind of communicating and doing the traffic workflow.  So even in the event of one compromise, the entire system doesn't get compromised.  So I would say just storing both of them in separate apps or separate agents would still give you that security.  But eventually all of them would get reversible unless you want to invest on another server where the mobile actually communicates with that.  So I would say that it's basically removed from the mobile device entirely. That would be an overkill.  Yeah.  The dynamic use case with OR, there's always a little bit iffy.  So pre-registering always removes that attack vector.  So if it is dynamic, then you could definitely do competition controls on the server end.  Yeah.  If you have other questions, you can definitely reach out to us, but we are out of time.  So thank you for being a great audience.
Lak_Shmi_Sudheer_-_Who_Dis_Who_Dis_The_Right_Way_T_BE4xBwJOjkU_0_107.png Lak_Shmi_Sudheer_-_Who_Dis_Who_Dis_The_Right_Way_T_BE4xBwJOjkU_108_695.png Lak_Shmi_Sudheer_-_Who_Dis_Who_Dis_The_Right_Way_T_BE4xBwJOjkU_696_779.png Lak_Shmi_Sudheer_-_Who_Dis_Who_Dis_The_Right_Way_T_BE4xBwJOjkU_780_1067.png Lak_Shmi_Sudheer_-_Who_Dis_Who_Dis_The_Right_Way_T_BE4xBwJOjkU_1068_1439.png Lak_Shmi_Sudheer_-_Who_Dis_Who_Dis_The_Right_Way_T_BE4xBwJOjkU_1440_2207.png Lak_Shmi_Sudheer_-_Who_Dis_Who_Dis_The_Right_Way_T_BE4xBwJOjkU_2208_3467.png Lak_Shmi_Sudheer_-_Who_Dis_Who_Dis_The_Right_Way_T_BE4xBwJOjkU_3468_3527.png Lak_Shmi_Sudheer_-_Who_Dis_Who_Dis_The_Right_Way_T_BE4xBwJOjkU_3528_4331.png Lak_Shmi_Sudheer_-_Who_Dis_Who_Dis_The_Right_Way_T_BE4xBwJOjkU_4332_5231.png Lak_Shmi_Sudheer_-_Who_Dis_Who_Dis_The_Right_Way_T_BE4xBwJOjkU_5232_6539.png Lak_Shmi_Sudheer_-_Who_Dis_Who_Dis_The_Right_Way_T_BE4xBwJOjkU_6540_7835.png Lak_Shmi_Sudheer_-_Who_Dis_Who_Dis_The_Right_Way_T_BE4xBwJOjkU_7836_8063.png Lak_Shmi_Sudheer_-_Who_Dis_Who_Dis_The_Right_Way_T_BE4xBwJOjkU_8064_8423.png Lak_Shmi_Sudheer_-_Who_Dis_Who_Dis_The_Right_Way_T_BE4xBwJOjkU_8424_8771.png Lak_Shmi_Sudheer_-_Who_Dis_Who_Dis_The_Right_Way_T_BE4xBwJOjkU_8772_9263.png Lak_Shmi_Sudheer_-_Who_Dis_Who_Dis_The_Right_Way_T_BE4xBwJOjkU_9264_10715.png Lak_Shmi_Sudheer_-_Who_Dis_Who_Dis_The_Right_Way_T_BE4xBwJOjkU_10716_10799.png Lak_Shmi_Sudheer_-_Who_Dis_Who_Dis_The_Right_Way_T_BE4xBwJOjkU_10800_10955.png Lak_Shmi_Sudheer_-_Who_Dis_Who_Dis_The_Right_Way_T_BE4xBwJOjkU_10956_11267.png Lak_Shmi_Sudheer_-_Who_Dis_Who_Dis_The_Right_Way_T_BE4xBwJOjkU_11268_12071.png Lak_Shmi_Sudheer_-_Who_Dis_Who_Dis_The_Right_Way_T_BE4xBwJOjkU_12072_12515.png Lak_Shmi_Sudheer_-_Who_Dis_Who_Dis_The_Right_Way_T_BE4xBwJOjkU_12516_12623.png Lak_Shmi_Sudheer_-_Who_Dis_Who_Dis_The_Right_Way_T_BE4xBwJOjkU_12624_13067.png Lak_Shmi_Sudheer_-_Who_Dis_Who_Dis_The_Right_Way_T_BE4xBwJOjkU_13068_14447.png Lak_Shmi_Sudheer_-_Who_Dis_Who_Dis_The_Right_Way_T_BE4xBwJOjkU_14448_16931.png Lak_Shmi_Sudheer_-_Who_Dis_Who_Dis_The_Right_Way_T_BE4xBwJOjkU_16932_18875.png Lak_Shmi_Sudheer_-_Who_Dis_Who_Dis_The_Right_Way_T_BE4xBwJOjkU_18876_20627.png Lak_Shmi_Sudheer_-_Who_Dis_Who_Dis_The_Right_Way_T_BE4xBwJOjkU_20628_21575.png Lak_Shmi_Sudheer_-_Who_Dis_Who_Dis_The_Right_Way_T_BE4xBwJOjkU_21576_22199.png Lak_Shmi_Sudheer_-_Who_Dis_Who_Dis_The_Right_Way_T_BE4xBwJOjkU_22200_22439.png Lak_Shmi_Sudheer_-_Who_Dis_Who_Dis_The_Right_Way_T_BE4xBwJOjkU_22440_23495.png Lak_Shmi_Sudheer_-_Who_Dis_Who_Dis_The_Right_Way_T_BE4xBwJOjkU_23496_23987.png Lak_Shmi_Sudheer_-_Who_Dis_Who_Dis_The_Right_Way_T_BE4xBwJOjkU_23988_24827.png Lak_Shmi_Sudheer_-_Who_Dis_Who_Dis_The_Right_Way_T_BE4xBwJOjkU_24828_25415.png Lak_Shmi_Sudheer_-_Who_Dis_Who_Dis_The_Right_Way_T_BE4xBwJOjkU_25416_27455.png Lak_Shmi_Sudheer_-_Who_Dis_Who_Dis_The_Right_Way_T_BE4xBwJOjkU_27456_28595.png Lak_Shmi_Sudheer_-_Who_Dis_Who_Dis_The_Right_Way_T_BE4xBwJOjkU_28596_28703.png Lak_Shmi_Sudheer_-_Who_Dis_Who_Dis_The_Right_Way_T_BE4xBwJOjkU_28704_28751.png Lak_Shmi_Sudheer_-_Who_Dis_Who_Dis_The_Right_Way_T_BE4xBwJOjkU_28752_28907.png Lak_Shmi_Sudheer_-_Who_Dis_Who_Dis_The_Right_Way_T_BE4xBwJOjkU_28908_29003.png Lak_Shmi_Sudheer_-_Who_Dis_Who_Dis_The_Right_Way_T_BE4xBwJOjkU_29004_29051.png Lak_Shmi_Sudheer_-_Who_Dis_Who_Dis_The_Right_Way_T_BE4xBwJOjkU_29052_29579.png Lak_Shmi_Sudheer_-_Who_Dis_Who_Dis_The_Right_Way_T_BE4xBwJOjkU_29580_30155.png Lak_Shmi_Sudheer_-_Who_Dis_Who_Dis_The_Right_Way_T_BE4xBwJOjkU_30156_30203.png Lak_Shmi_Sudheer_-_Who_Dis_Who_Dis_The_Right_Way_T_BE4xBwJOjkU_30204_32615.png Lak_Shmi_Sudheer_-_Who_Dis_Who_Dis_The_Right_Way_T_BE4xBwJOjkU_32616_35495.png Lak_Shmi_Sudheer_-_Who_Dis_Who_Dis_The_Right_Way_T_BE4xBwJOjkU_35496_37499.png Lak_Shmi_Sudheer_-_Who_Dis_Who_Dis_The_Right_Way_T_BE4xBwJOjkU_37500_38663.png Lak_Shmi_Sudheer_-_Who_Dis_Who_Dis_The_Right_Way_T_BE4xBwJOjkU_38664_40871.png Lak_Shmi_Sudheer_-_Who_Dis_Who_Dis_The_Right_Way_T_BE4xBwJOjkU_40872_41927.png Lak_Shmi_Sudheer_-_Who_Dis_Who_Dis_The_Right_Way_T_BE4xBwJOjkU_41928_43847.png Lak_Shmi_Sudheer_-_Who_Dis_Who_Dis_The_Right_Way_T_BE4xBwJOjkU_43848_43979.png Lak_Shmi_Sudheer_-_Who_Dis_Who_Dis_The_Right_Way_T_BE4xBwJOjkU_43980_44051.png Lak_Shmi_Sudheer_-_Who_Dis_Who_Dis_The_Right_Way_T_BE4xBwJOjkU_44052_44843.png Lak_Shmi_Sudheer_-_Who_Dis_Who_Dis_The_Right_Way_T_BE4xBwJOjkU_44844_45287.png Lak_Shmi_Sudheer_-_Who_Dis_Who_Dis_The_Right_Way_T_BE4xBwJOjkU_45288_47675.png Lak_Shmi_Sudheer_-_Who_Dis_Who_Dis_The_Right_Way_T_BE4xBwJOjkU_47676_47771.png Lak_Shmi_Sudheer_-_Who_Dis_Who_Dis_The_Right_Way_T_BE4xBwJOjkU_47772_48287.png Lak_Shmi_Sudheer_-_Who_Dis_Who_Dis_The_Right_Way_T_BE4xBwJOjkU_48288_51791.png Lak_Shmi_Sudheer_-_Who_Dis_Who_Dis_The_Right_Way_T_BE4xBwJOjkU_51792_53327.png Lak_Shmi_Sudheer_-_Who_Dis_Who_Dis_The_Right_Way_T_BE4xBwJOjkU_53328_54683.png Lak_Shmi_Sudheer_-_Who_Dis_Who_Dis_The_Right_Way_T_BE4xBwJOjkU_54684_55739.png Lak_Shmi_Sudheer_-_Who_Dis_Who_Dis_The_Right_Way_T_BE4xBwJOjkU_55740_57215.png Lak_Shmi_Sudheer_-_Who_Dis_Who_Dis_The_Right_Way_T_BE4xBwJOjkU_57216_57947.png Lak_Shmi_Sudheer_-_Who_Dis_Who_Dis_The_Right_Way_T_BE4xBwJOjkU_57948_58643.png Lak_Shmi_Sudheer_-_Who_Dis_Who_Dis_The_Right_Way_T_BE4xBwJOjkU_58644_59507.png Lak_Shmi_Sudheer_-_Who_Dis_Who_Dis_The_Right_Way_T_BE4xBwJOjkU_59508_60083.png Lak_Shmi_Sudheer_-_Who_Dis_Who_Dis_The_Right_Way_T_BE4xBwJOjkU_60084_62243.png Lak_Shmi_Sudheer_-_Who_Dis_Who_Dis_The_Right_Way_T_BE4xBwJOjkU_62244_63035.png Lak_Shmi_Sudheer_-_Who_Dis_Who_Dis_The_Right_Way_T_BE4xBwJOjkU_63036_63239.png Lak_Shmi_Sudheer_-_Who_Dis_Who_Dis_The_Right_Way_T_BE4xBwJOjkU_63240_64247.png Lak_Shmi_Sudheer_-_Who_Dis_Who_Dis_The_Right_Way_T_BE4xBwJOjkU_64248_65879.png Lak_Shmi_Sudheer_-_Who_Dis_Who_Dis_The_Right_Way_T_BE4xBwJOjkU_65880_66395.png Lak_Shmi_Sudheer_-_Who_Dis_Who_Dis_The_Right_Way_T_BE4xBwJOjkU_66396_66443.png Lak_Shmi_Sudheer_-_Who_Dis_Who_Dis_The_Right_Way_T_BE4xBwJOjkU_66444_66515.png Lak_Shmi_Sudheer_-_Who_Dis_Who_Dis_The_Right_Way_T_BE4xBwJOjkU_66516_70631.png Lak_Shmi_Sudheer_-_Who_Dis_Who_Dis_The_Right_Way_T_BE4xBwJOjkU_70632_72479.png Lak_Shmi_Sudheer_-_Who_Dis_Who_Dis_The_Right_Way_T_BE4xBwJOjkU_72480_72494.png