Common API Security Pitfalls - Philippe De Ryck

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
all right good morning everyone for the people in the back we have some premium seating right here up front if you want to sit on the first row we have one spot left I think so fix some other spots on the second and third row so if you want to sit down don't don't hesitate just come up and we got to talk about common API security pitfalls so this talk is gonna be an overview of a lot of problems that can happen in API a lot of problems you might have in your API and a lot of problems I'm gonna try to help you solve in your API and I started talking about this actually quite a long time ago in 2017 when they added something to the OS top-10 so the OS stop then is a list of the ten most dangerous availabilities in web applications and they make this list every couple of years and in 2010 2017 they proposed to add under protected api's to that list of vulnerabilities some things happen in the community a lot of people were very discontent with what top 10 has become and the whole project shifted gears a bit and this is appeared in the final version but didn't matter because the seed was planted people realize like holy crap you're building all these api-based applications and this is a real problem you need to start thinking about security specifically for that and that's why last year they launched the API security project in Ross Perot and this API security project focuses on everything API security related they even builds a separate top ten for issues about API security so if you're interested in API secured if you want to get started with API security I suggest to take a look at that because it's a treasure trove of information I'm not going to talk about the top ten of API security issues some of them will be in there some of them might not be I'm gonna talk about my own experience I'm gonna talk about what I see when I talk to developers when I teach developers about security or when I look at their systems I encounter often the same things which is what I distilled into this API security pitfall stock just to make sure that we're all on the same page I want to sketch a little totally lava facial architecture diagram so what we're doing is we're building an application today it's gonna be typically a web application in a lot of cases a front-end so you're loading your front-end your client-side JavaScript based application where there is angular or react or view doesn't matter your bootstrapping that in browser that's step one that moment you have an empty shell you have something that doesn't really do anything useful because typically you need back-end systems to make that work and that back-end system is going to be your API it's gonna be fetching data from an API rendering displaying that and when you perform an operation it's gonna push that operation back to the API to actually persist that later on we're going to talk about the API part we're not going to talk about the frontline security part which also means that in this case it's also very relevant for people building other types of clients if you build a mobile client or a desktop application or whatever if it's backed by an API I can guarantee that almost every one of these issues we're going to talk about is going to be relevant I didn't count them so I have no idea how many we're gonna cover but that gives me flexibility to cut it short we're running late but we're gonna be totally fine this image is a good starting point there's a lot of people well sometimes you have full stack developer sometimes you have to split between front end and back end but off people think about this image as a whole well II actually only the top part is usually relevant for security because the top part is where the things happen where the data is where the operations happen and a very good example is tinder you can swipe left and right for looking for a partner totally based on appearances so it's absolutely not what we stand for as a society but sure it's probably very useful by the way everything I'm telling you now is totally anecdotal because I have a wife and otherwise she would be very very displeased with my behavior but as it turns out apparently you can also see who likes you so other people can see your profile and you can even of course they like you the app is trying to sell you a premium subscription by showing you blurred images like hey these people like you you want to see what they look like right so why not pay us and we'll get you access to that data it turns out that the blurring of the images is a front-end operation the mobile app just pulls in the image and blurs it and then shows it to you so of course if you know a bit about computers you're like mmm do I want to pay for that no let's just spend a lot of time figuring out how it works and you'll find the API call that you can actually use to get that image and with that you can actually get the image and so on and so on so somebody else figured this out they analyzed the web application figure out the API endpoints we make the call coming from the iOS application and they got the images just like that and that brings us to the first important pitfall your API is a real attack surface it's not a front-end yes there are some security things you need to address in front ends but usually it's gonna be about your API that's where you should focus most of your efforts when you look for security problems and a lot of API is over expose data not only images but just fetching like full JSON objects and then displaying three fields in the front-end and yeah everybody everything else is hidden right well not if somebody figures out what the API calls are what the traffic looks like they can grab all of that data just like that so that's definitely one thing to keep in mind also sets very good team we're gonna talk about a lot of authorization issues because in security it often comes down to authorization to preventing somebody from doing something they're not supposed to be doing which is authorization we need some things to make that work I will talk about that later first another authorization problem I really like these cases not to make fun of companies getting it wrong but to illustrate you that these are real things because when I talk about these things people are like yeah nobody does that in practice like come on you know better than to do that well apparently not what happened here t-mobile mobile phone operator they get cake they can give you access to your account you want to access your account information is gonna be an API call with your phone number phone number is a unique identifier for your account makes sense since cell phone numbers are unique and linked to your account so why not the problem here is called unsecure direct object references it's an old problem has been around for a while and what a problem actually means is that if I substitute my phone number for your phone number I'm gonna get your account information just like that then I figure out what his phone number is and bam I got his account information and so on and so on and what they actually did check is whether you were authenticated but he never checked if you were the actual person the owner of that account and were supposed to access an information it's an unsecure of that reference happened to t-mobile happen to telefónica in Spain to AT&T in the US and to Verizon in the US as well all of the phone companies apparently have a very similar vulnerability and happens in other cases as well insurance documents linked to by numbers of identifier in the URL and then it starts with zero zero zero zero 200 for somebody might try zero zero zero 203 and boom there you go out of document and so on and so on you can start enumerating there used to be a problem in old Web Apps we have the same thing in api's just like that we call it differently it's called broken object level access control but it's the same essential problem under the hood and these things are really really common I can guarantee you that in this room five to ten people if they go look at their API on Monday they will find this problem absolutely that common and why does it exist because we build applications with two turtles we learn about REST API is in node in ten minutes and in ten minutes there's not going to be any security in there I can tell you that takes a lot longer to talk about security but this is okay because it's about the rest paradigm and you learn how to build a to-do application of course and it's about fetching tasks so you can read a task with a task identifier here is a request or parameter stop task ID you can delete tasks with a task identifier of course you send it a delete request and it will make sure the task disappears and when you build a first application your first API like that is gonna be awesome like oh this is pretty cool of course then you're going to think about users like hey but I don't have a single user I'm like I have different users so let's learn about how to do identification and users and all of these things and that information that tutorial that course is gonna talk about how you have to implement authentication checks like is the user log didn't know Oh in that case let's send them a 401 otherwise go ahead and perform that operation and that's exactly what t-mobile and all the other phone companies also did but then you have to think further then you have to think about who's allowed to access this particular task who can read it and you have to implement explicit authorization checks and these things are often missing because often people don't talk about that and they're not very easy to implement it's a very difficult problem to solve and unless you go to your application and you look for the absence of that code you're not gonna spot this yes with testing you'll find the fact that somebody is should be logged in I can access that that's gonna be in your test but unless you thought about this problem explicitly it's not gonna be in your tests and you might be missing that particular piece of code and the cases I talked about illustrate that this thing is really really common all right brings us here lack of proper authorization always check both authentication status and object level access control check if the user is allowed to access these things yes or no and again that's not an easy problem to solve even in a task manager like the one that showed you here this can get complicated really quickly I use a task manager that I share with my wife for example or full household and life is basically in a to-do application but that means that deciding if somebody's ought to read a task means did this person create a task lock okay that's fine or are they part of a shared project which also gives them access to this task which gets complicated really really quickly it's not an easy check to do at a single single location in your application that brings us here so you're gonna get a call to a back-end like hey I want to fetch this information and there's gonna be some authorization information we'll talk about that in a second there might be some custom headers or token in the header something like that and then the call is gonna invoke other services in your application architecture and I'm explicitly or deliberately vague about this services whether it's a Mike or service or another layer in your monolith application doesn't matter because this happens in all types of applications there's all things involved there's a data access layer there's maybe a layer to a control or doing something and so on and so on and at each of these layers you typically make authorization checks like is the user logged in oh yeah that's that's good then let's move ahead with the skull and then maybe there you want to check all this user is allowed to read this task that's cool and that part does something else based on different customers and different projects maybe sir there's going to be a customer specific ID check and God knows what else the user specific ID check or something like that and all of these checks together that's your authorization policy and this is something really interesting because if you if I had to unsecure the assessment I'm typically sitting around the table with five to six of the engineers that built the application and we talked about how to handle security and when I asked them like hey if this calls come call comes in how do you know that this you our application is supposed or allowed to access this particular object and of the six people are on the table five people are going to be looking at job because that's the guy that built this authorization policy and Java is gonna be like oh crap I'm on the spot now and you see him thinking like hmm so this call comes in so we have a token in your requests we're going to take this parameter out of the token and that comes out of the database and then based on this so yeah I think we have discovered that's the good case yeah this is fine the bad case is like oh crap and they start writing like an authorization rule on the fly like let's just update the code to add this but these things are hard to analyze they're hard to audit and if you have a policy like this were a few people only a few people in an organization have the full mental model of that it's gonna be insanely difficult to actually alter that policy you have no idea what checks are and forced our checks are not enforced and if these people are sick or leave the company nobody knows and that's why you need a centralized authorization policy these checks are good as a defense in that mechanism absolutely use them but preferably you have one place where you can specify an authorization policy whether that's in code or a separate declarative policy run by a policy agent doesn't really matter here but you need to have an auditable centralized authorization policy you need to be able to go to one place in your application say like this is what we enforce on incoming API calls and that will give you a good idea and that if somebody asks like hey have recovered this particular authorization problem for this particular endpoint you can go ahead and select oh we probably should add that or oh yeah this is covered here's the policy and that's a very good way of making authorization checks all right by the way if you want to grab a copy of the slides I've pushed the tweet out so you can go to my Twitter feed and grab a full PDF with a lot more slides than what I'm talking about here so that's definitely a good way to spend your weekend reading about API security all right or just do it mommy I know work-life balance you I understand that so let's do it on Monday that's also fine all right catherization like I said we're gonna talk a lot about authorization authorization or propagating authentication states that's essentially what we're doing we're logging in once as a user for every subsequent call we need to know oh it's Phillip making the call so we can make authorization decisions and this used to be a fairly simple thing to do you had a client and you had a back-end this is the old days this is Internet Explorer and a PHP or Perl back end with a my sequel database remember those times life was a lot simpler back then anyway your application grew you have a lot more users maybe there was like a Firefox user in there sure let's make sure that works as well but essentially you had us a number of clients and a manageable number of back-end servers and that's a typical application model this is called stateful because the server's typically keep session state a PHP session ID pointing to a server-side session object keeping track of states such as is the user authenticated yes what's his user name Phillip that's essentially what's going on in the rest world this is considered to be evil like no and never ever keep State on a server in a restaurant because we have stateless services honestly I don't really agree with that there's nothing wrong with keeping state right here on back-end systems there's something wrong with writing stateful code actually agree if you write code that behaves differently based on what's in that object that might not be the right thing to do but if you're making authorization decisions the server-side state that works we know how to do that we know how to use sticky sessions or session replication on the server and your engineers if there have been doing web development for 20 years they know how to do that and if you're building a small to medium scale application where you know that you'll have a few hundred users and nothing more often my recommendations just use this mechanism it works of course if you're building something like this we have a bunch of services like 20,000 Amazon instances and a gazillion clients this is probably not gonna work very well and hit it's not the use case for that anymore then you have to move towards the stateless systems and it makes a lot of sense but what I see is a lot of people read about these rest api's and statelessness and they look at Twitter how is Twitter doing things and then they replicate is their application it takes a lot of effort to get it right we're gonna talk about that in a second a lot of effort to learn about these things to get it right only to realize after it's like yeah we only have a hundred users so why did we do that what's wrong with our Java session ID in a spring boot application it works first modules to actually do that and it makes a lot of sense in certain applications so I'm not saying one is better than the other I'm saying one it's a bit easier than the other shirt but if you want to move from stateful server-side sessions to stateless sessions with tokens probably do it for the right reasons do it for scalability not because somebody said so that you have to do that in a blog post about how to build your first angular application make sure you think this true PHP session IDs probably not sequential and single-digit but you get the idea this is a server-side State server-side State lives in this nice server-side environment in memory which is considered to be a fairly secure environment somebody can modify that information trust me that's gonna be the least of your problems you're gonna be screwed anyway however if we move this to the client the back end becomes stateless which is awesome but our data now lives in a very insecure environment where everybody who knows how to open up local storage can start tampering with that information in the browser it's like oh here's the value authenticated false well let's change that to true and see what happens I can guarantee you nurse API is out there like oh you're authenticated oh here's the data that happened in practice there's API so you can change admin equals false to true an API it's like Oh welcome admin BAM just like that of course we know better so let's not talk about that but how do you protect the data you need integrity protection absolutely you need to be able to detect unauthorized changes to this information you might also need confidentiality because sir site memory confidential lo storage if you put sensitive information there health care information financial information it is considered to be a safe place to keep that information client-side storage not so much it might be breaking God knows how many regulations by pushing the data into the client so think about these things in practice we're gonna think about that and learn about that you're probably gonna end up here a JSON web token a job and the tilt is sorry for the sign language people here the next part is not gonna be very straightforward to translate that try to stick with me so a job is a way to represent JSON data and we all know what a job looks like typically on a job has a header a payload for actual data lifts and a signature and we get that job you need to want to grab that data out of here that data is going to be the useful piece of information that you want to do something with such as make authorization decisions here's a code example of how to do that in Java and this is a very interesting example because I often show this in my training courses and ask people what's wrong with this and you have a group of 20 people in the room and this happens generally on every occasion and you're looking at this like hmm that's interesting there's probably one meaningful line of code yet people are like I know something I can't really pinpoint it and it's like one or two persons yeah I think you're just getting the data out but you're not verifying any integrity you don't know whether you can trust that data and they're right this lime tree the decode function is simply decoding the payload from base64 to Jason well in this case to a Java object actually this is the or a better way to do things verify the signature first before we're getting the data out the result is the same in line 6 we get a decoded shot object just like we did in line 3 but the implications are a lot more serious here because the first code example is extremely vulnerable anybody can give you anything they want and the second is the way to get it right and I don't blame you Vela purrs for this because honestly we don't need the documentation for every function that we ever call that's why it should have been called in security code or decode without verifying signature because that would tell you as a developer like mmm that's probably not the one I need and you will be able to find other solutions this is just an illustration of why moving these things to the client makes things more complicated don't miss handle client side session data if you want to call it that our authentication state or authorization state whatever you want to call it I honestly don't care about the name I care about what it represents and that's exactly what this is about don't miss handle that all right when we talk about jobs for a while now why because they have become the de facto standard to do these things and there's a lot of things wrong with them usually let's talk about a pretty purple part here the payloads that's where the actual data lives that payloads often looks like this I can guarantee you if you open up Google or sorry if you open up go I should say in your brave browser which is actually pretty awesome you can Google for how to do token-based authentication angular apps and you're gonna find something like this like just authenticate user and push some stuff in an adjacent web token and send it to the client that off we go and people love it because it's a stateless paradigm if you look back at your very old PHP application that we all know that you're still running but that's a different story it's gonna look like this you're gonna get a session ID a meaningless identifier you're gonna have to look it up at the database and then you get some vault database or memory or Redis cache or whatever you need to get some session data and you can make your authorization decisions state on the server that are it's in the database or whatnot if you deploy this in different geographical zones it's not gonna work very well and this mutton the new paradigm that's often called token-based authentication which is a very incorrect name but that's again not very important here looks like that beautiful right no more data stored on a server no more stay to manage or replicate no we can simply get it out of a job by verifying the signature and we're good to go however when you implement a system like this you have vastly different properties because here you have full control over what's happening you can control sessions you know how many active sessions there are you can kill a session if you want to you can revoke access to a session and so on here you have nothing and especially if you use it as a session this token that you now have is gonna be valid for 8 hours 12 hours a day and if somebody loses that token if somebody steals that token one way or another you're in a role of trouble because there's no way to kill it there's no way to even tell application like don't accept this anymore this one is bad doesn't exist of course if you think about this upfront you can build systems you can build for example a list of revoke tokens a very common approach like what if we give every token an identifier and then we keep a list of bad identifiers so we know that this one shouldn't be accepted anymore and you get something like this so you have your token and you have a list a database or a cache or whatever somewhere with a list of known bad identifiers so you have to go check it every time a token comes in to make sure if it's still valid or not and that's under the assumption that you kept these identifiers in the first place linked to specific users or specific devices because if you haven't have if you don't have that list upfront then this doesn't even work very well again to show you that there's a lot of things wrong it's lightly pushing that state to the client it doesn't work like that somebody on the internet called you P has been saying that for a very long time you wrote a blog post a very ran T blog post which is actually very spot on and of course people started suggesting solutions like changing keys or keeping lists of revoked identifiers so we build a very sarcastic flowchart to tell all of them that are wrong because everything ends up either in usability problems or security problems all of them brings us soo-ji I suggest you read it it's actually really interesting brings us to the takeaway here don't mistake a job for a session a job is just a way to represent data securely by adding integrity protection and confidentiality if you want to but it doesn't do anything it's not a session it's not revocable and if you want to use juts like all artists you need a whole supporting ecosystem to make that work that's why a lot is so complicated because it ensures that there's a central party in control of issuing tokens and making sure when the token is renewed that they're allowed to get a new token adding revoke ability and all of these things into the mix all right back to a job we talked about is a few times shots have integrity protection they are signed by the issuer meaning once they're signed a receiver is able to verify whether the job has been changed in between yes or no which is good otherwise I could change my user ID from one two three four five six seven eight nine zero to something else and I will become another person that's not possible because of a signature the blue part here is a signature a few things about signatures you'll often find them as an H Mac more on that in a second don't use super-secret H Maki as the secret to sign that a check and if you use something else don't put that on a PowerPoint slide and broadcast that to the world again seems obvious but people have production found production systems using Kies copy pasted from lock posts like a blog post explaining how this works something like super-secret H Mickey copy/paste production code oh yeah this seems to work very well don't do it why because that's how it here's how an h-back works an HVAC takes this input data in a jot world that's the header and the payload and I'm going to push it through an HVAC function a dedicated cryptographic function that takes a secret key as input super secret H Mickey and spits out an HVAC that H Mac is uniquely linked to this data and this key and that's what you add to the job that's the blue part in a job you push that out to the client and everybody's happy that's how you assigned jobs that way you get when you receive a job and then at the data and the payload I'm going to push that through the hmx function again with the secret key and out comes an H Mac and now it can compare these two H max you can compare the original one with a new one and if you're the same then you know that the message of the job that data has not been changed in the meantime since issuing that job and if they did change maybe somebody added a white space maybe somebody's changed a zero into a one we don't care if it's not valid we reject it and we kick it out and that's how an H Mac works there's one big elephant on this slide one big glaring problem this works perfectly fine in your application sorry are targeting you if you build an application that issues a job and receives a job you can verify that signature very easy use key volts to put that secret in you get it or you ask the vault to verify that signature and you're done awesome however if you make friends at a conference they want to give their application shots they're going to need to verify the integrity of that job so you might be tempted to give them your secret as well don't do that you can never keep a secret more than one application basically or one person unless you kill them which is a lot harder with applications of it people also not recommended by the way because hmx have a second signature scheme H sorry shots h max are only useful within one single isolated application everybody else should be using astrometric signatures which are much more awesome but also a bit harder to implement but you should go to the effort of doing that what's going to happen here is we're going to use a signature algorithm again dedicated cryptographic function and we give it a data and a private key and out comes a signature which we add to the data and we push it out to the client in this case and when it comes back we get a data in the signature and we use again a specialized function to verify that signature which takes the data and the original signature as inputs along with a public key and it will tell you yes or no true or false exception or no exception depending on how it's implemented and then it's the same when it's a good a go thumbs up or whatever that means that a data has not been changed and that the data has been signed by the private key belong to this specific public key and when something doesn't match either the data changed or it was signed by a different key honestly we don't care and we don't want it in this mechanism much more beautiful to use because this means if you are issuing juts to all the conference attendees all you need to give them is your public key and the word says it itself public key everybody can know that because nobody can use that to generate Falacci of tokens in your name the only thing that can do that is a private key which as the word implies you keep private you store that in your key vault and give nobody else access to that private key and that is how you handle child signatures and this is the only useful thing in most applications even within your own trust zone even within your microservice architecture every service issuing jobs should have their own private public key pair allowing you to compartmentalize that allowing to verify who actually generated this job and whether you want to trust that yes or no very very very important and again something that I often see implemented in a different way all right one of the reason shots are so hard is because they're crypto basically it's not about Jason though it's about signing and encrypting whenever you sign something think about our scenario adhere our friend upfront which is totally gonna hate me for targeting in it's giving all of you with jobs it's giving all of you a job and you want to verify that how do you know his public key you don't right that's gonna be a hard problem and the same happens in an architecture you need to get hold of the proper the right key one simple way would be for him to write to add is key to the wall of keys let's say we have a wall of keys here and it gives it an identifier like my key is number 17 so now you can include a claim in the header of your child called K ID the key identifier and in the case here it would be 17 allowing you to go to the list of public keys 17 audacity key I need to use you can verify that child so if you have a bunch of keys floating around in your organization you can go to your key vault and ask the key vault like hey give me the public key with ID 17 and off you go or along a random UID which is a bit harder to pronounce in a presentation but realistic as implementation all right that's very nice if you have a centralized way to access keys doesn't work very well in distributed scenarios let's say Google is issuing jobs and I need to verify them well just probably not gonna be a very easy way for me to grab Google's public key in a reliable way which is why the spec has some other mechanisms as well they have a GK you claim and a GK you allows the issuer to embed a URL holding a set of public keys the represented in a JSON format which is absolutely ugly for public keys but doesn't matter you never have to look at it as a human so we're all good but essentially here's a JSON web key set a set of public keys I can fetch it from there and then the key identifier is gonna say like Oh from that those keys just use the key with this ID and I can now verify the signature and if Google decides to start using new keys tomorrow they just published a public key on that endpoint change the key ID in the next issue jut and again my service can go there 50 keys verify the signature and trust the data coming from Google all right if you don't like JSON web Keys you can also do the same with certificates x.509 certificates there you would use the x5 you claim you give it a URL pointing to a certificate and you can fetch that key information from there that's essentially how key management works in a job world this is something that I've honestly never seen implemented in a real world system people think about this then they don't do it but you need to implement key management but you need to be careful with that because once you start doing that you'll end up with a scenario like this somebody gives you a job it's signed by a private key so you need to verify that with a public key you can find the key set to chase a file with keys on evil example.com like hmm your application has been implemented because you listened to like half of this talk and not the other half so it's like oh yeah so the gku I'm gonna fetch your skis I'm gonna find the key with this identifier like this K ID oh yeah I found it verify the signature oh it's fellas awesome so your flip I'm gonna trust you and give you access to my account this is not good the problem here is that you're using information from a sign shot without the ability to verify the signature you're relying on this header info but you don't know whether you can trust the job yet which is kind of a chicken and egg problem which doesn't have a good solution that's why specs that rely on this like open ID connect have an out-of-band configuration channel if you choose to sign in with Google on a website in the end that website is going to receive a JSON web token signed by Google saying who you are within the Google ecosystem your account with an identifier and a name but the application is not gonna dynamically fetch Google's keys no when you configure your application to allow log in with Google you tell it that you want to log in with Google and the service or libraries are gonna go to this location dot well-known slash operating configuration at on accounts on google.com on a fixed hard-coded domain and you're gonna go there and that is a JSON file with the Open ID Connect configuration and it's gonna have a gt3 wks your I claim telling you like oh the keys for Google or this identity provider I'm using 4 are 0 are located in this specific location and you can fetch your skis before even having received the first token an out-of-band configuration channel on a trusted location because your point specifically your application to Google and that way you can sidestep this whole thrusting the key thing I'm not saying this is the only way I'm saying this is a fairly straightforward way to sidestep that whole trust issue something to definitely keep in mind in rural applications all right enough about jobs now but I would say it's gonna be better now no let's talk about cookies everybody loves cookies right no this is a PHP era PHP session ID not hopefully not 42 but this meaningless identifier it's long identifiers with some entropy in there but whatever you get the idea that's the old way of doing things somebody that most people something that most people absolutely hate because cookies have a very very bad reputation the modern way is using an authorization header so many applications today are using the authorization header with bearer as a type of authorization value and then a token you can recognize the EU IJ that's a base64 encoding of a JSON object to start at least so you know it's probably gonna eat Jason in this case a child those are the two approaches and I often get asked like what should we use cookies are tokens and I'm like that makes no sense because a cookie is a mechanism to transport data from a client to the server and the authorization header is the same thing but what you put in there is a string it's a text-based file you can put in there whatever you want so why not put your job in a cookie or your identifier in an authorization header if you want to switch it up and people always look skeptical with this light like what the hell is he talking about like nobody does that well this is an identifier if you're using OAuth you have a concept called a reference token which is an identifier to state kept by the authorization server on the server side it's called an access token but it's just a random ID and if you're using OAuth you also have the jobs base tokens access tokens that's called self-contained tokens but nobody tells you what to do with them the spec is even like once you have that token how you contact the server with a token that's your business we don't care about that and there's actually pros and cons to all of these let me show you a few highlights of things that always come up when I first asked you he who hears using cookies Twitter ap is like nobody maybe I should have asked a baseline first who is building api's like okay we're good it's like nobody raises their hand then of course the other talks must have really been not interesting I would say but awesome many people don't use cookies with your abs like no we don't do that but I've seen a lot of systems that are hosting resources is at least in a web application hosting resources that require authorization checks for example if you're loading images or documents or whatever images with an image tag you might want to enforce some authorization if this is per customer or per project or pre user you need to make authorization decisions before giving out that image if you don't do that by the way you have an unsecure direct object reference problem stick skip back thirty minutes and look at that again because that's exactly the problem you have there but guess what if you're loading an image tag in a web application the browser doesn't send custom authorization headers with bear and your application cannot send that either and let them tell you unless you do some really dirty workarounds guess what the browser does send when you add an image tag to a page cookies if you have a cookie for that domain brass is gonna send that cookie along and I've seen a lot of people go towards the header based approach like yeah we're gonna implement this authorization header in angular with an interceptor and it's awesome and then a couple of months later or implementing resource loading or lazy loading for admin templates or whatever and they discover that there's no information there and what they typically do is they come up with a hybrid mechanism like let's add a cookie to the application for these cases with some authorization so I think about this upfront same thing for web sockets opening a web socket you type well you write JavaScript code new web sockets something-something no authorization header the difference cookies for that domain the browser will send cookies to that back-end and that might be a very good way to implement authorization I fully agree that in a non web world cookies have no place for building something that's not a web application absolutely get rid of cookies 100% but if it's a web app think about this upfront think about the pros and cons I have a few have a nice overview slide here of the pros and cons boats headers can contain string based values whatever you want in that header key they remind cookies only work well with a single domain that's how cookies work well the authorization header you can send it anywhere completing 10 api's on 10 different domains probably want to use authorization headers and not cookies cookies are handled automatically by the browser which is very good and a bad thing but the authorization header requires you to write custom code which might mean you introduced some vulnerabilities and then finally cookies are always present in a web world cookies are added to dom resource loading to web circuits to cross-origin calls with xhr if you enable that while the authorization header is only there when your application is in control of that request if you're sending it from JavaScript sure you can add it otherwise you'll need either a very dirty work around with service workers which is not recommended or there's no information there and that's the truth about this cookies in a work world are the only thing that worked really well because the browser handles them automatically again when I talk about API executing courses my disclaimer is I have no answers I only have options I can give you the options I can tell you what to look for but the end the final decision is up to you you decide what's gonna work for your application and honestly in this case both of them work quite well that takes me straight to one of my pet peeves security if you're riding something with an authorization header you are riding application code to make it happen you are writing code to take something out of a response from the server stored somewhere in a browser and reattach it on outgoing requests and one of the questions you will have is where do I store this thing where do I put it like in a browser would you store things like there's local storage sessions stored in index DB and and so on and so on it's like in memory maybe who knows it's a really really difficult problem and a lot of people struggle with that and you'll find advice online telling you to be really careful because if you put in a look of storage your risk cross-site scripting attacks if the attacker injects some JavaScript in the application they can read everything that's in local storage and ship it off somewhere else and if that thing was a token that's held for eight hours the next 7 hours and 59 minutes are now gonna be very fun for the user whose token got stolen which is a problem and some people have solutions like you know what we have something called HTTP only cookies so we can put it in a cookie and then mark it HTP only minier javascript is not allowed to read it and that takes away that danger right these are HTTP only cookies depends on where you're standing where this is secure and not from the outside looks like oh yeah the door's locked until somebody pushes that and off you go because the problem is not the fact that you hide a value the problem is that you're running code from the attacker that's the real threat cross-site scripting means game over and this is something that comes up over and over again people at this is a tweet from me from last year I usually don't go looking for these things and calling people out but if they ask me like can you look at my blog post and I have some time I'll do it but I'm gonna tell it like it is this is bad advice because yes hiding this token from an attacker and cross-site scripting seems to solve the problem but it's it only sidesteps it addresses one symptom and that's it you're still running code from the attacker the attacker can still do whatever you want and need location they can change the UI if you're building a banking app they can add transactions to the list of transactions to do and hide them in the interface users will not even know that the transaction is there the attacker has already won so hiding one little token yes it's gonna make it harder to attack your application that's true means that your eight-year-old script kiddie that broke in it's not gonna be able to exploit that they'll be like oh there's nothing in the local search let's move on to the next one you got away good there awesome but a real attacker a skilled attacker a pen tester is gonna be like okay let's let's see what you're doing oh I can start making API calls I can do whatever I want she using oh I take an embed an iframe and get a new access token that way before it's hidden away in memory or HT only cookies or whatever it doesn't solve the problem so my advice is do not ever underestimate cross-site scripting and instead of looking for like that the best place to put this little value in the browser spend that time learning how to prevent cross-site scripting in your application much more useful because that's the real problem not the hiding of this value who is building anger front ends awesome angular solves most of cross-site scripting issues for you look on my website I have some advice on angular who's building react apps yeah bad news for you guys we react it's not really good at preventing cross-site scripting so I built a full full one page cheat sheet on how to do that correctly again go to my Twitter feed you'll find the cheat sheet it's really available you can download it today and start using it on Monday at your job to look for cross-site scripting in your reactives if you have questions I'll be around the rest of the day so you can harass me after my talk as well alright I was still good shoot your API accept this input it's like blah that is one unfortunate username probably not I don't know maybe maybe not there's a one here so probably you actually want a numerical value so this is bad input and many people talked about this in the first steps like input validation oh my god you need input validation I don't but I'm talking about it now towards the end lack of input validation is absolutely a security problem you need to have input validation input validation gets rid of known malicious data if you get five megabytes of password data probably not a real password just saying yes 25 characters 30 characters that's acceptable so capital 100 everything larger than hub characters is striped DDoS your server by sending large passwords reject that however input validation will never be your full defense to the API accept this data as input no some people say no some people are like huh that's interesting well it depends if you didn't accept the first one because it was sequel injection and you shouldn't accept this one either because it's sequel injection however if you're relying on input validation you're gonna have a bad time first of all this is a valid email address so if you input validate this with an RFC email address validate the validation library it's gonna be like yeah totally valid if it causes sequel injection problems you have bigger problems in your API because input validation is never going to be your only or primary defense input validation can never stop things like sequel injection command injection cross-site scripting it can only get rid of known bad data to keep the crazy out that's why we have these guys at our front door checking your badge when you come in input validation if your badge is missing they're being like oh you're not allowed in here and of course everybody with a pic the camera and a scanner or a printer can actually create a badge it looks good enough to get in anyway we have no other security here because everyone should learn about secure development but input validation will never save your butt for security it's good as a first line of defense but never as the only defense keep that in mind you should have it but it will never save you from the actual attack that's why we have parameterization for sequel queries where we have output encoding or sanitization for cross-site scripting escaping for command injection and so on the real Defense's happen at output I'm not an input time very very important consideration all right final takeaway what happens when chocolate ice cream goes wrong now none of my kids think this is ice cream so apparently it was supposed to be ice cream but that failed miserably not sure whether a different color would have helped them with it just any way things go wrong there's well hopefully you'll never have an issue but in reality you're likely going to have a security issue at a certain point in time it's gonna happen so the best thing you can do is think about this upfront like what if something goes wrong and one of the best defenses that you can use is compartmentalization split things up into smaller components if you're building an API that serves a public part of an application and an authenticated part and an admin part that should not be one API that should be three separate api's preferably running on three separate subdomains or domains or whatever because that helps you compartmentalize that means if something goes wrong in a public part of the application it's gonna be separated from the other parts it means you'll be able to detect cross application or cross trust boundary communication and reject those requests immediately and this is something that holds for both back-end systems and front-end systems and so on always try to think about these things and reduce the impact and you can today you can build very seamless user experience even with multiple compartmentalized applications working as one big application so always keep that in mind because this is the thing that's gonna save your butt one Oh a vulnerability in our front page which is public without authentication whoops let's fix that but if you compartmentalize that from the other indicated part attenti gated users will not suffer from that vulnerability or suffer less and that is going to be really really important question everything don't just do something because you wrote one blog post it says that's how you supposed to do things question what I'm saying ask me those questions and I'll try to argue with you on why I'm right usually I am sometimes I'm not but that's why I only talk about security not about other things but seriously question these things healthy debate is useful because you need to understand the different viewpoints and the nuances to be able to make accurate security decisions in your applications alright thank you very much for listening grab the slides and the sheet cheese from Twitter and ask any questions you want to right now or the rest of the day at the conference thanks for being here
Info
Channel: NDC Conferences
Views: 14,046
Rating: 4.9384613 out of 5
Keywords: Philippe De Ryck, Security, Web, API, REST, NDC, London, 2020
Id: dDZNDVO5EFQ
Channel Id: undefined
Length: 49min 32sec (2972 seconds)
Published: Wed Feb 26 2020
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.