Web Security Essentials Live Workshop with Mike Sherov Part 1
Mike Sherov: [0:00] Hi, everyone. I am Mike. I am from New York. I work for a company called Skillshare, but I also teach on Egghead.io. Security has been a passion of mine. I am a...I guess you would call that a principle engineer at this point of time. I have been in the industry for 16 years.
[0:19] I have done both frontend work and backend work. One of the most persistent things and one of the things I think is the most important skill that I have is that I know a little bit about security.
[0:30] The reason why I say a little bit about security is that I think it's really hard to know everything there is about security. Even having a little bit of knowledge, even having the basics of each of these things, and knowing where to look is more important than knowing it all 100 percent.
[0:48] We're still finding vulnerabilities in software that's written 30 years ago. Security, the job is never done. We're here to just open your eyes, have everyone aware of some of the security best practices that are out there. By no means, this is an exhaustive list.
[1:06] This is just the beginning. There's a ton of great resources out there. One is called Owasp, O-W-A-S-P. If you want to check it out, it's owasp.org. This is a great foundation. They have solutions to basically every security problem you want. I am just here to show you the tip of the iceberg. Some of them are the essential bits of security.
[1:37] You should have, by this point, get your system set up. If you're using Windows, it turns out you're going to need to run these fallback commands for getting the code running. I would just say that big part of this workshop isn't necessarily to have the code running. It would be better for you to be able to walk through and do it yourself.
[1:59] Even if you can't get the code running, understanding the principles behind each of these attacks, and the mitigations is far, far more important. A lot of the cases, the code that we are writing for each exercise is one or two lines, but knowing why were those one or two lines is important is the important beep there.
[2:17] It's best to know the principles behind the security best practices and just to know the specific lines of code you need to write.
[2:24] The code is set up in a pretty unique way where all the exercises are in exercises folder, which I can show you over here. If you open up your repo, we have exercises 1 through 17. They're all within that folder. They don't have their own package.json file.
[2:48] If you're familiar with the Node programming environment, Node modules can live a directory above. We have one set of Node modules for all the exercises. If you got to the top-level directory and npm install, you'll get all of the dependencies you'll need for the entire set of exercises.
[3:06] You won't need to npm install more than once. You'll just be working from each of the exercises' repositories, running some commands to put your website live, and then inspecting and exploring from there.
[3:21] That's basically what we'll be doing. We'll be going through each of the exercises, talking about the best practices and why they matter, and moving on. The first thing I think is really important for everyone to know is that, again, I just want to underscore again that this is the tip of the iceberg.
[3:43] There is this great article on Medium called "Everything Is Broken." It just gives you the depths of despair that is the modern web environment. Every website is broken in at least one or two ways. Realizing that and realizing that we need to do everything we can to overcome the default broken nature of a website is critically important.
[4:12] I could show you what might seem to be a small website can be irredeemably broken in a whole bunch of ways. What I'm going to do is start off now. I just want to pause for a second. Does anyone have any questions about what we'll be doing and how the workshop will be working?
[4:36] Also, I'll encourage again, for all the participants that are here, just if you have a question, go ahead and shout it out. I'll stop you or ask you to pause if I want to move the question along, but in general we won't have to.
[4:51] I'm going to start. What I have here is I have my VS code. Is the font size OK for everybody over here? Can everyone see the code? If you can't see the code, go ahead and give a minus-one either in the chat or in the participants list. Yeah, Will. Thanks, Will. That's about as big as I can probably stomach it without losing headroom.
[5:28] If you're using Windows, you'll want to make sure you're running VS Code or whatever your programming environment is as an administrator and running a terminal as an administrator. If you're using Mac or Linux, we'll get away with using sudo.
[5:41] I'll start off by being in the top-level directory. Here I am in Web Security Essentials. The first thing I'll do is I will sudo run npm install. In general, it's not necessarily a good idea to sudo npm install. In this case we're installing packages that would require administrator privileges, so I've sudo npm installed all my packages.
[6:11] That will get us every Node module we need to run this course. We'll be going through each exercise to run from there. Our very first exercise is we want to start our site up and poke around our website and discover what might be vulnerable about our website. The very first thing I'm going to do is I'm going to descend into the CD exercises directory.
[6:38] I have two terminals running. One will be used for our website, which is localhost.charlesproxy.com. One will be used for evil.com, which is the attacker website that will be attacking us. We're putting on two hats. We'll be switching between being the user, the site administrator, and the attacker. We'll have to continue to switch contexts to understand who is doing what.
[7:02] The first thing I'm doing here is I'm going into my exercises01 directory. I'm going to sudo npm start. That will give me a website running at localhost on port 80. I'm using a site called Charles Proxy. charlesproxy.com has a URL called localhost.charlesproxy.com.
[7:26] It will just forward requests along to localhost, but it gives you a real URL so that the browser behaves as if this is a site on the Internet rather than a site that's local to your computer. There's a couple of things about Chrome and Firefox that do different behavior if they know the URL you're looking at is localhost.
[7:47] The first thing you'll notice is that our website has a login prompt. As soon as you have any information that requires login, you have cookies or authentication. Ours does as well. I'm going to put in my really secure username of mikesherov and my really secure password of the number one. Hit submit. Here I am, logged in now.
[8:12] In America, we have this thing called Social Security numbers. Social Security numbers is a piece of information that is considered private to you, although a lot of people don't necessarily treat it private. You could use it to get information about yourself that someone who doesn't know your Social Security number wouldn't be able to get.
[8:31] Here on my site, we bravely display my username, mikesherov. We display that my Social Security number is indeed 123-45-6789. We have a spot to write messages. We should think about these messages as if someone else impersonated me and wrote a message on my behalf, it could be damaging my reputation.
[8:52] We want to make sure that only I can actually submit a message. If I type "Hello" and hit submit, it'll say, "Message from Mike Sherov. Hello." If I write "Hi," it'll produce "Hi." If I hit this button "Send hello message," it'll just also submit another hello.
[9:12] This is a really small surface area. We have a login form. We have a page that displays some information. We have a messaging form and a messaging button. To go through the code, what our site looks like...I'm in the wrong site.
[9:39] This is an Express application, so we're requiring Express. We use Express Sessions. Sessions is a way that given a cookie on a user's computer, you can associate that piece of information with some information that's stored on the server.
[9:58] If we store a cookie with a session ID of one on the server, when the cookie gets sent over that says one, the server can say, "OK, what's the information associated with that number one?"
[10:10] This session ID is usually a pretty long number, so that it can't be guessed. In this case, Express generates its own. We could see this if we open the console. We click on network. We could see that -- where is this -- that our request to localhost.charlesproxy.com transmitted a cookie called connect.sid with this long, giant string.
[10:43] This is how sites work. They transmit this long string back and forth. The server associates that long string some other relevant information, like my username and my Social Security number. The website can then display that information back to me.
[11:01] We're using Express. We're using Express Session, which gives Express session abilities. We have a login route, we have a messages route, and we're saying that we have an Express app that will...This line could be ignored, but it essentially says that we will be able to parse form submissions from a website.
[11:26] We're using the session plugin, which I just showed. I need to make this terminal a bit smaller. These parameters don't really matter that much. The only thing we need to know is that we have some cookie settings, and we ignore HTTP-only for right now. It's irrelevant.
[11:48] The fact is that sessions are HTTP-only by default. That's a good security default in Express. We're manually turning them off, so that we could see a vulnerability. We should ignore that it's false right now. We should pretend that we implemented this without knowing about HTTP-only cookies, which we'll get to in a later lesson.
[12:08] Then some other stuff happens. It isn't as important at this moment. Then we listen on port 80. This says we have an app, it has session management, we're listening on port 80. We then have our login route.
[12:24] Our login route will read a username and password from the request body. It will look up the user's username in our database. Now, this is in memory. In your real application, you would store this in a database. You'd encode the password in a much more significant way.
[12:46] This course doesn't cover that, because that's really back end security. We're talking more about web security today. It looks up the username. It makes sure the passwords match. If they do, it saves information in the session, the username and the Social Security number.
[13:01] Then it'll redirect them back to the home page. Otherwise, if the passwords don't match, it'll redirect them back to login. Then if you get the login route, it'll just print the form. We have a login form that will submit to login with method post. It has an input for a username, and it has an input for password.
[13:24] We also have messages, which essentially the home screen. This is the main route. We'll accept a post request, and if the user is logged in, if we have the user parameter that gets set by logging in in the login route, then we could say, "Message from the user," based on their username, and what message they submitted.
[13:51] That's how that works. In this, we'll redirect back to this route again via get. All get does is it will either, if there is no user, redirect them to login, otherwise it will print out what we saw before. It will print out today's latest messages.
[14:09] It'll print out their username and their Social Security number, print out a form for them to submit the message, and then some buttons to send hello. Then some JavaScript that controls that form. For good measure, on our site, we're also including a copy of jQuery, a nod back to, I guess, a few years ago, when jQuery was the thing everyone was using.
[14:39] The point of this is here is that websites typically have external, third-party code, and we'll need a way to deal with third-party code. For right now, it's just there to be there. We don't have to pay attention too much to jQuery.
[14:55] This is our application. Our application uses sessions and uses session management in order to submit messages and to display messages to a logged-in user. We discovered two things. We discovered first that we have this session ID, which gives us a right and ability to be the user.
[15:18] If someone were to steal this session ID, they can impersonate us as the user. That's a really critical thing to protect. Typically, when you see security attacks, the session ID is often a thing people are trying to get access to.
[15:40] We'll be spending a lot of time in the upcoming exercises to protect that session ID. We also have to, maybe even more importantly, we have this piece of critical information, the Social Security number, that we want to protect.
[15:57] We have a two-pronged thing here. We have the session ID, which gets us through impersonate. The session ID also gives us access to the Social Security number, which is something we would want to protect as well.
[16:11] This brings us to the point in time where we talk about what attacks can happen here. I want to just pause for one second. I know I went through the code fast, mostly because it's not the main thing we're talking about at this moment.
[16:30] We'll investigate the code a little bit more as we go on. Is there any questions we have so far about starting up our site, looking at the session ID, and looking at the code so far? OK. I'll take that silence as yes, that everyone is all good.
[16:56] Part of the prereqs for this course was to download a thing called Charles. If you do Android or iOS development, you might be using Charles already to proxy information. What Charles is -- and you can get this at charlesproxy.com -- is this is a web proxy.
[17:19] A web proxy installs itself on your computer and listens for all outbound traffic. If I refresh this page a couple times and go back to Charles, I could see that there was a request to localhost.charlesproxy.com for the slash endpoint.
[17:41] It gives me basically everything that Chrome would give me, as far as network requests go. If I have anything else running, like a tracker is in the background or if Dropbox is pinging Dropbox at something just to do a ping, this will all start appearing in the left-hand side here. Charles Proxy is stand-in right now. There you go, there's Dropbox. Dropbox is communicating with itself.
[18:15] Charles Proxy, in this case, because we're doing local development, is going to be a stand in for what's known as a packet sniffer. Charles Proxy and/or a packet sniffer are what's known as men in the middle. You've probably heard of this quote notion of the man-in-the-middle attack.
[18:35] What a man-in-the-middle attack is, is when someone is able to intercept your communication between your computer and the server you're trying to connect to. This is actually a pretty big, huge problem maybe 10 years ago. Raise your hand or tell us in the chat if you've ever heard of the term Firesheep.
[19:04] Back in the day, what used to happen is that websites would protect their login forms with HTTPS. That way, the username and password were submitted over HTTPS. They'd have their other routes, like their home page of whatever it is, go over HTTP.
[19:26] As we can see from Charles proxy, our man-in-the-middle, we can see that the raw request to localhost.charlesproxy.com contains our session ID. We're transmitting this over HTTP, which is clear text. Meaning anyone who could sniff our traffic can read it.
[19:52] In the days before prevalent WiFi, this wasn't a big deal. You'd have to physically compromise a wired connection in order to be a man-in-the-middle in that case. Free public WiFi or even WEP-enabled WiFi are two versions of WiFi where you can just sniff anyone else's packets who is connected to that network. Meaning you could read their traffic.
[20:23] In 2010, someone developed a program called Firesheep. What it would do is you could go into a coffee shop. You could connect to local public WiFi. You could sniff everyone's packets. This program was purposely built and designed to detect Facebook, Twitter, GitHub, and any other site's session IDs, and in a nice, neat, little UI display to the attacker who they could login as.
[20:53] You can go and log in as somebody else on Facebook. You could log in as somebody on Twitter. All you need to do is go to a place that had free public WiFi, listen for other people's traffic, and attack. Very quickly, everyone started moving over to HTTPS because, again, you could see right here that the session ID is stealable.
[21:19] We're saying this Charles Proxy thing is a man-in-the-middle. It's a good proxy for what Firesheep and other packet sniffers were able to do. We could even impersonate. I can right-click on this request. I could submit a real request saying, "How are you?" Go back over to Charles. I could see that this post transmitted all of this information with the message, "How are you?"
[21:53] I can copy this request as cURL. cURL is a command line tool that lets you make HTTP requests. I've copied this thing as cURL. I can go back over to my text editor, paste this in, do some word wrap. Most of this stuff is junk. I don't need the Pragma header, a Cache-Control header, origin. I don't need this or the user agent.
[22:19] All I really need is the cookie, the cookie containing the session ID, and my message. I could say, "Hacked." I could paste that right into my command line. Again, I'm the attacker. I'm not anyone else. Hit Enter. Cool. I can go back to my Chrome, and I could refresh over here. Here we are. You've just been hacked.
[23:05] I think that's the essence of man-in-the-middle attack. You send over some piece of information containing your session ID. In clear text, attacker sniffs those packets, steals the request, modifies it, and replaces it with their own custom message. This is man-in-the-middle.
[23:31] The way we're going to do this exercise right now is we're going to talk about, and I'll have you all answer. We can do this in one of two ways. We could either do breakout rooms or we can do just this with all our attendance at the same time. People raising their hand and then I can call on them or you can just unmute yourself and say the answer.
[23:56] We'll just ask questions about this just to confirm understanding. Science shows us that if we replay the information that we just had, over time, we'll solidify our understanding. I guess the first question I'd like to ask the group just to check for understanding is, what is a session ID? Anyone have a good answer to that question based upon what we've learned so far?
Raymond: [24:35] I'll break the ice here. This is Raymond from Barcelona.
Mike: [24:39] Hi, Raymond.
Raymond: [24:40] Hi. How are you doing? For me, session ID is identifier of someone that if you are able to grab it and pick it, then you can act as that person or that user.
Mike: [24:58] That's great. Just to add to that, it's typically stored in a cookie and I guess transmitted automatically over every request.
Raymond: [25:06] That's right.
Mike: [25:07] Cool. What is Charles Proxy? Looking for someone other than Raymond.
Chen: [25:20] Mike, can you hear me?
Mike: [25:21] Yes. Who is this, Chen?
Chen: [25:22] This is Chen. Yes, sir.
Mike: [25:24] Hi.
Chen: [25:25] In simple words, it's just a packet sniffer that shows what's being sent in the request if someone wants to get hold of it or just poking around or whatever really.
Mike: [25:42] Great. Cool. Perfect. That's great. What is a man-in-the-middle attack?
Will: [25:48] A man-in-the-middle attack is when someone is able to intercept your information while it's being sent to the server?
Mike: [25:58] That's right, Will. Great. It's essentially, just to rephrase a little bit, it's attack where the information being transferred between a client and a server is listened to and sniffed by a third party. Cool. When a session ID is stolen, either be a man-in-the-middle or some other method, that's called a session hijacking attack. We're going to be using that term session hijacking. Cool.
[26:32] The thing we want to do now is understand how to prevent this. The problem if we look at Charles is that for everything that's gone over HTTP, we can see the full request. If you look down here at all the things that have been pinging the Internet while we've been talking, so many things were pinging the Internet on your computer all the time. It's unbelievable. We see that they all have locks.
[27:08] I think I have to sneeze. It went away. If you look at, for example code.jquery.com, that was over HTTPS. HTTPS, by default, unless you have the certificate as the man-in-the-middle, you get garbled nonsense. You get the encrypted version of all the information. You don't get to know what the session ID is.
[27:39] This is why HTTPS is such an important principle. It is a shame that the Internet by default is HTTP. When I say that Internet is by default HTTP, what I mean is if I just type localhost.charlesproxy.com and hit Enter, it's going to assume the HTTP protocol, not the HTTPS protocol. In order to get HTTPS, I have to specifically type in HTTPS into the front of the URL.
[28:10] We are going to set up HTTPS for our local development environment right now. In production, you're going to want to set up HTTPS everywhere for your application. The ways in which you could do that are many and manifest. The goal of this workshop isn't to teach you how to set up HTTPS for any of the possible ways in which you could do it. It's to show you that what happens when you do do it.
[28:42] In the world of Express, what I'm going to do is start from my site index. What I want to do once set is I first want to use...There is a package that is a secure by default version of Express. This is called HTTPS local host. It's the main reason why you want to run npm install as root because it requires root privileges.
[29:33] What this does is, for your local environments, if you've done the HTTPS development locally before, you might have seen something like this image. If your local [inaudible] HTTPS locally and it's like, "Oh, security certificate is not trusted."
[29:56] The reason why that is, is every computer has a central store of which certificates are considered to be root authorities. We just haven't added that certificate yet to the root authority list. To do add to root authority list, you could avoid this not trusted symbol for local development.
[30:18] What HTTP local host does is once you actually go to use it, it will do the work to generate a certificate and unlock on your computer that it is a valid root certificate authority. We're going to go ahead and we're going to say, "Local host is HTTPS local host." We're going to switch our ports from port 80. Default port for the Internet for HTTP is 80. Default port for HTTPS is 443.
[30:51] Instead of starting up a normal Express server, we're going to start up a local host version of the Express server. This is just Express wrapped with HTTPS and say that it's specifically a Express server for this domain. For good measure, over here, my little message, I could say, "Open up HTTPS rather than HTTP." I could start my server back up again.
[31:38] Now, because I tried to connect on HTTP, it's saying I don't know where thing exists. If I put in HTTPS, I now get our site again. I type in Mike Sherov, I put my password. I type in, "Hello." I hit Submit. I can go back to Charles Proxy. I could see that we have a now unbreakable version. We're no longer leaking our session ID because we're only connecting over HTTPS. That's our first exercise.
[32:26] This is our first actual coding exercise. Essentially, you will take five minutes now, or as long as we need, to go do this ourselves. I encourage everyone to, in your top-level directory, if you haven't started yet, to run npm install and then to send into the exercises 02 directory.
[32:58] Make your modifications, one again requiring local host, changing the port, using it instead of Express, and then opening up HTTPS on your network by changing this to HTTPS. When you're done, you'll again start sudo npm start.
[33:23] Once that's running, you'll visit https://localhost.charlesproxy.com. If you get stuck, in the directory, there is a solution link. In the solution link, step one is going to tell you a URL that shows you the actual diff that you're trying to perform. That should be that.
[33:49] Again, we'll take five minutes starting now to do that. Don't worry too much about the time. If we need a little bit more, we'll take a little bit more. I'll also open up in case anyone has any questions at this moment. Cool. Let's go ahead and do that. I'll mute myself for a little bit.
[34:17] If you're having trouble getting any of this stuff running, also, feel free to talk in the chat. Thomas, are you running a sudo or are you running npm start or sudo npm start?
Thomas: [34:55] I'm running this as sudo npm start. I did a sudo npm install because I'm using NVM, node version manager. Usually, I don't use sudo. Maybe it has something to do with that.
Mike: [35:11] It's possible. I'm going to see if...
Thomas: [35:17] I can just wipe out Node modules and try it again.
Mike: [35:22] Let's try that. Are you on a VPN by any chance, Thomas?
Thomas: [36:10] Not right now. No.
Mike: [36:35] You don't have a proxy running locally?
Thomas: [36:39] No. I don't seem to have. I will try just [inaudible] different browser. [inaudible] .
Mike: [37:03] You're getting an error message in Chrome, tunnel connection failed?
Thomas: [37:16] Yeah. 443. HTTPS is 443 by default, right?
Mike: [37:19] Yes. I've never had that. You're getting error on Chrome, too, Rohit. Is it the same tunnel connection failed? If you're using Windows [inaudible] you are, Rohit. Sorry, is that Naomi? Can I mute you for a second, Naomi? I'm getting a little feedback.
Naomi: [37:54] Yeah, sure.
Mike: [37:59] Rohit, can you paste some more of the error in the chat?
Rohit: [38:06] I'm not getting any error, but I think this certificate file is not getting downloaded for some reason. [inaudible] I think the first one is the first exercise, which was [inaudible] executable. I think the file is not getting downloaded for some reason.
Mike: [38:37] I'm not sure. I think we're going to have to...
Thomas: [38:49] I think in my case, I didn't change the 443 in its source code.
Mike: [38:58] That's good. All right, Thomas, that's...
Thomas: [39:00] [inaudible] it's running on port 80 but it's mismatched with the HTTPS protocol, right?
Mike: [39:06] Yeah. Good. Now it's on 443. Thomas, I'm going to mute you again. I think it's Rohit, we'll have to figure how to...
Rohit: [39:21] Mike, can you just tell me the URL from where we are downloading the certificate? Maybe I'll check, getting blocked somewhere.
Mike: [39:30] Cool. I want to move on to the next exercise, and then we'll pick up debugging this again when we do that. Naomi, you had a question? Naomi?
Naomi: [39:48] No. We just joined late, sorry. We didn't get the URL.
Mike: [39:51] Sorry. Welcome.
Naomi: [39:54] Thank you.
Mike: [39:57] Cool. Just to catch up, we went over discovering that a session ID is the vulnerable piece of information that we're trying to protect. Typically, a session ID can get stolen via a man-in-the-middle attack, using Charles Proxy to act as our middle man.
[40:20] We have just installed and ran exercise two. If you look at the solution folder in exercise two, the solution.md file in exercise two gives you instructions on how to complete that. We'll try to catch you up at the beginning of exercise three for any other support issues. Cool. Welcome aboard.
[40:52] We have our website over HTTPS. I think Thomas actually illustrated this point perfectly, is that it's easy to get confused between port 80 and port 443. Again, our default protocol of the Internet is HTTP. If I type in localhost.charlesproxy.com, I've now have a failure again. This screen means that you can connect to our local server.
[41:22] The thing is, is we made our site work over HTTPS, but we turned off HTTP and so most people can't hit us, which is bad. You want people who want to type in our URL to be able to visit our website. That would be a good thing.
[41:38] What we need to do is we need to redirect port 80 to port 443. The way that we can do that is spin up a separate application that will listen on port 80 and just redirect people to port 443. What I'm going to do again is I'm going to now go into exercises 03 directory. I'm going to have my site. What I have here is I have my secure version of the site running on port 443. Here is where we start listening on that port.
[42:27] What I'm going to want to do is create another Express application. I just say, "Reader application equals Express, readerApp.ListenOnPort80." All this says is I have an Express application. This is going to be listening on the default HTTP port. I need to give this application some behavior.
[42:49] Express has middleware. If you're familiar with the concept of middleware and the request-response life cycle, middleware functions just say, "Run this function every time a request comes in and do some specific behavior." In this case, I'm going to say that the behavior I want is to return the response.
[43:11] First parameter to middleware is request. Second parameter is response. I'm actually going to make that same response, so I don't have an unclear variable. I'm going to say response redirect. Where I'm going to redirect to is the HTTPS version of this site. HTTPS followed by our domain, which again is localhost.charlesproxy.com, followed by req.url.
[43:43] In the request variable in Express middleware, it will store everything past the domain part, which is called the path in a variable called URL. What this says is that when I receive a hit on port 80, I will redirect the request to the HTTPS version of the same exact URL. I can go ahead and start this up again. The joys of having a secure password, you have to type a bunch of times.
[44:22] Now, I can refresh and even though I typed in HTTP, it redirected me to the HTTPS version. You could see...Sorry. Did someone have a question? You could see that at first, it makes a request to http://localhost.charlesproxy.com/login. Let's actually start up a secondary window here. I'm going to do another just so we could start from scratch.
[45:08] We could see that, at first, we have a request of 200. I'm going to go ahead and clear cookies. I went to application. I'm going to clear out my cookies from our localhost.charlesproxy site. It's not our first request. Our first 200 does not...I guess it does include a cookie. That's the problem. Sorry. I confused myself for a second.
[45:37] We see that our request to HTTPS includes a cookie. We also see that if I type in my HTTP URL, first, we get a 302, which redirects us to the HTTPS version. Then we make request again to the HTTPS version. The browser makes two requests. First, it makes request for the HTTP version.
[46:05] Service says, "No, sorry, use this URL instead." Client says, "OK, I'm going to use that URL instead." The problem here is that even though we're redirecting HTTP to HTTPS, that first request over HTTP is still transmitting our cookie.
[46:26] If I go back to Charles, and I clear everything just to show no tricks, and I type in my HTTP URL, even though it eventually gets to HTTPS and looks like it went to HTTPS, here we are right back with our original problem again. We are transmitting our session ID cookie over clear text.
[46:59] We have the same problem again, but at least we have now not made our website broken for HTTP users. We'll have to solve that problem next. What we're going to do is we're going to go ahead and take five minutes to add our HTTP redirect application.
[47:19] Once again, if you go to the three-directory, you should be able to...For Naomi and friends, in the top-level directory of Web Security Essentials, you should be able to do sudo npm install, which should install our dependencies. Then you should be able to [inaudible] into exercises. In this case, exercises 03. Then you should be able to run sudo npm start. That will run your server after making your changes.
[47:53] Also, again, for everyone's benefit, solution.md contains a link to the actual code you need to make a change to. We'll do some Q&A questions after another, let's call it, four minutes of this, at one o'clock. Cool?
Will: [48:19] Could you explain again what's the middleware function?
Mike: [48:24] Sure. Great question, Will. We'll answer that. I also want to just once again give a plug for the notion that that's Express-specific. I'm happy to explain it. The fundamentals of this problem are still one level up.
[48:40] A middleware function is a set of functions that, when you make a request through an Express application, it will execute all the middleware functions in the order in which they were registered. Any of them could change and modify behavior. For example, a session middleware will add the ability to have a request.session object that gets carried forth between the different requests.
[49:15] This middleware we wrote here is it takes the request in and will automatically respond to move to another URL. Middleware is just a set of functions that runs in order, modifying the default behavior of all possible requests. Does that help, Will?
Will: [49:38] Yeah, that does. Thank you.
Mike: [49:53] I guess I'm giving the answer away by having it on the screen. I'll move away from it. Does anyone else have any other questions? I know, Rohit, you might still be experiencing that executable issue. I'm not 100 percent sure how to work around that at the moment.
Rohit: [50:23] I got this error. I know that it's not able to connect to the server. Anyways, we'll move forward. Maybe I'll try it from a different network connection.
Mike: [50:44] You could always delete your Node modules and start again to try to get that same server back. Cool. As folks are wrapping that up, if anyone has wrapped it up, I want to ask a couple of questions to the group. I think the first question that I'd like to talk about now is, how does HTTPS help prevent man-in-the-middle attacks? If anyone has done...Go ahead.
Will: [51:27] You're unable to see basically sustainability because of its encryption.
Mike: [51:33] That's right. Right. Exactly. By encrypting information between the two parties. Also third party has the decryption keys or the private key pair. A private public key pair, they can't decrypt it. It's essentially protected.
[51:50] Cool. Why isn't it sufficient to only serve the log-in pages over ACTPS, and do ACTP wherever else?
Chris: [52:06] I guess, because the token's is being passed with every request.
Mike: [52:14] That's right, Chris. The token is passed by every request. Again, it isn't just usually being passed through [inaudible] protect, although we do want to protect that too. We also want to protect the session ID. Only HTPS everywhere would do that.
[52:40] One more question I want to ask is, why are we now in this lesson, why do we have to listen for HTTPS traffic and re-direct, rather than just listening on HTTP? Why do we have to listen on HTTP and re-direct HTTPS? Why can't we just listen on HTTPS?
Audience Member: [52:56] If we listen over just HTTPS, since the Internet defaults to HTTP we would block out a lot of people.
Mike: [53:08] Right, that's true. Even with this re-direct in place, is there any traffic now being served over HTTP?
Audience Member: [53:17] The first request goes through re-direct.
Mike: [53:33] I think we're going to come back to it, unless anyone feels like they could use another 30 seconds or so?
[53:46] Great. Now we're left with the same problem we started with. Maybe a little bit less, because we're not transmitting our social security number of HTTP, we're only submitted our session ID, which I guess gives you one level removed of protection. Our problem is that we are still sending the cookies over HTTP. We need to only send the cookies over HTTPS.
[54:34] Thankfully, there is a flag for cookies called secure. If you look at our application, and you look at our cookies for localhost.charlesproxy.com, just put in my user name and password, you can see that Chrome will list all of the properties. This one is not an HTTP alone only, it's not a secure cookie, it's not a same-site cookie. We're going to learn what all three of these are, but first we want to learn what secure is.
[55:02] A secure cookie will say only send this cookie if the connection that's being made is over HTTPS. It's exactly what we want. This is thankfully a one-line change and in the Express world, we can say for cookie secure true. We'll start our site back up, in our session middleware configuration we'll clear these cookies, we'll refresh, and if we did it right, we get this little checkmark.
[55:59] How do we know everything went right? Well, we can log into our site and we can do our HTTP version and we can see that our HTTP version -- where is it? -- did not send the cookie. It'd be in the cookie request header, which it's not.
[56:24] It's only in the cookie request header for HTTPS. Now this, you might want to rest on your laurels and say, "We did it, we're now finally secure from man-in-the-middle attacks. We are setting up HTTP to HTTPS. We have our session ID cookie is secure."
[56:48] The problem with this is that it's on a per cookie basis, right? A really important principle of security is, you want to have secure defaults. Because secure isn't a default flag for cookies, any member of your team, or a future version of you, can go ahead and add another cookie to their website, and forget to set the secure flag.
[57:12] Boom, you have the same problem all over again. It's on a per cookie basis. If you're ever adding any other cookies you are still just as vulnerable, and still just as likely to make a mistake.
[57:23] This is a really fundamental principle of security is, you want defense in-depth. Defense in-depth means, if there are two ways to mitigate a vulnerability, implement both. That way, if one of them fails, the other one can still save you.
[57:41] The expression that's used is called "belt and suspenders." The expression is, "If you want to keep your pants up, to be guaranteed to have your pants stay up, you have to wear a belt and suspenders."
[57:54] If your suspenders break, you still have your belt. If your belt breaks, you still have your suspenders. While we've solved our problem, we've only taken it one step of the way. I'm going to skip us taking our time to do this lesson locally. You could do it on your own, about one line of code to put secure true, and get to some questions here.
[58:21] To repeat, I'd love somebody else to answer the question, "What does the secure flag do?" Anyone want to answer? How about someone who hasn't spoken yet? Take a leap of faith.
Audience Member: [58:48] What's the question again?
Mike: [58:50] What does the secure cookie flag do?
Audience Member: [58:55] It makes the cookie only available to raise CCPS.
Mike: [58:58] That's right, and it protects the cookie from being transmitted as clear text, clear text being what HTTP transmits it.
[59:08] Just to repeat, even if we were redirecting all traffic to HTTPS, are we 100 percent secure? Are we guaranteed to only ever be sending cookie data over HTTPS? The answer is no, because the secure flag is on a per cookie basis.
[59:32] We are left with still our fundamental problem of even though we have a secure website, even though we're transmitting over HTTPS for most things, even though the cookie that we know of so far is only being sent over HTTP, we haven't prevented HTTP from being accessed.
[59:55] Can anyone guess how we solve that problem systemically? OK, there's this thing, it's called "HSTS." HSTS stands for HTTP Strict Transport Security.
[1:00:19] This is an HTTP header you could send on a response that says, "For all future requests, if the user types in HTTP and hits enter, on the browser we write that to HTTPS. Don't send me an HTTP request. Only send me the HTTPS request." The browser will re-write the request to HTTPS first. That's what we're going to do. That's what we're going to do now.
[1:00:54] We're going to go back to our code. We're going to use the magic of having our dependencies already installed for us. Let me just close some of these things.
[1:01:15] We are going to now install Helmet. Helmet is another piece of Express middleware, not to be confused with react-helmet, which is a React component that controls your head element of HTML. What Helmet does is it provides a set of middlewares for Express that enforce secure headers.
[1:01:48] In this case, we're going to use Helmet's HSTS middleware. The HSTS middleware takes a configuration object to configure the parts of the HSTS header. The first part of the HSTS header is max-age.
[1:02:09] This says this is how long the browser should attempt rewriting HTTPS to HTTP. Sorry, that the browser should spend rewriting HTTP to HTTPS, before it tries again to do HTTP. You don't want to be in a situation where you accidentally get rid of your SSL certificate, and now you just can't hit your site ever.
[1:02:33] You have to be able to set an expiration for when this happens. Now, the default recommended minimum is one year. That's 60 seconds, times 60 minutes, times 24 hours, times 365 days, which I like doing as one year.
[1:02:55] Second one is include subdomains. This tells the browser that, even if I'm on charlesproxy.com, this HSTS header applies to www.charlesproxy.com or localhost.charlesproxy.com. It applies to all subdomains the domain of this thing applies to.
[1:03:20] Lastly, but not least, it expects a preload. We're going to put in preload true. Now, what preload true does is it tells the browser that this HSTS header is eligible for the preload list, which I'll get to what it is in a minute.
[1:03:48] For right now, I'm going to fire this up. Oh, I just want to go to O5. We're going to watch closely. We're going to watch closely. We're going to connect over HTTP and hit enter. We could see that our very first request still went over HTTP. It still got 302, because the browser doesn't know about HSTS yet.
[1:04:33] Second request went to HTTP, and in the response, it included a strict transport security header. Maximum age is a year. It includes subdomains and preload. Now, if I again try...Oh, you're going to see my whole browser history, aren't you?
[1:04:59] Let's see. If I try HTTP, localhost, charlesproxy, we now get a 307. This 307 isn't even actually real. It didn't come from our server. It came from Chrome itself. Chrome said, "Internal redirect." The reason why it did an internal redirect is HSTS. Trust me, nothing ever went out to our server. Instead, it rewrote it to the HTTPS version.
[1:05:32] Now, we could look at this list of requests, and we could say that, for any given user, their browser is first going to hit one time over HTTP, get an HSTS response. Sorry, get a redirect response, go over HTTPS, get an HSTS response, and all future requests from this browser will be over HTTPS.
[1:06:00] This solves the problem almost completely. So very close to complete, because we still have the very, very, very, very first request from the browser to the server going over HTTP. Now, the reason why preload matters is, believe it or not, Google maintains an HSTS preload list.
[1:06:32] You could submit your domain to the HSTS preload list and say, "I want my website to always be over HTTPS." Then Google will ping your server, and it'll say, "If you have an STS header of at least a year, and it includes subdomains," and you say...
[1:06:54] Sorry, who's...? Sorry. You say preload, then it forever be on the preload list for that year. At that point, then your first request...Sorry, let me back up. When Google sees this entry when it's applying to apply you to the preload list, it then adds you to the preload list.
[1:07:21] Then browsers, their default behavior these days is it first checks the preload list before it ever connects to your website. If your site is on the preload list, it will change the default. At the very base level of the Internet, you can tell the browsers that your default protocol is HTTPS. Finally, finally the end. Then you never have to worry about any requests over HTTP again.
[1:07:58] Cool. This is, sorry, there's a couple questions in there. "HSTS doesn't work for older browsers." That's correct. What I always use for anything is can I use .com? I will always type in the thing that I care about here.
[1:08:17] You could see that HSTS exists on IE11, as of 2015, in all Edge browsers, and basically, every browser you can care about. Sorry, Chen but you missed the issues. Every browser, except for Opera Mini, which basically has nothing.
[1:08:35] If users are connecting to your site over IE6 to IE10, they're not going to have the effects of HSTS. There's really no workaround. You'll have to rely on your secure cookies at that point. This is, to answer David's question, David asks, "Is this like an A record?"
[1:08:58] An A record is a DNS entry. Believe it or not, HSTS preload list, I think, is like a slapped-together solution that doesn't use DNS or any of the core infrastructure of the Internet to accomplish this.
[1:09:22] Again, let's take five minutes now. We're going to go ahead, and we're going to once again require Helmet. We're going to use Helmet's HSTS middleware, and we're going to put a max age of a year, include subdomain's true, preload true.
[1:09:41] Once again, solutions are step one in the solution.md file, if you need help. We'll take four minutes or five minutes to do this. If anyone wants to ask questions out loud, I am happy to answer them. I also just want to say, Chan, I know you missed the last 25 minutes.
[1:10:02] There's going to be a recording of this entire workshop as well, so you'll get that, too. Sorry about that.
Chen: [1:10:09] Thank you, Mike.
Mike: [1:10:12] Does anyone have any questions around HSTS, preload list, or non-preload list?
Naomi: [1:10:20] Mike, do you want to talk about web server redirects? Not everyone's going to want to modify their app server to redirect something when they don't...
Mike: [1:10:34] Right, whichever server the client is connecting to, your origin server, if you're in a microservice architecture, you have essentially one of those services is the fronting machine. You do want to, at that level of the application, ensure that everything is going over HTTP.
[1:10:56] If you do get an HTTPS...Sorry, you want to make everything's over HTTPS. If you do get an HTTP request, you do want to have to modify your server to respond with a redirect. Does that answer the question, Naomi, or was I...
Naomi: [1:11:17] Yeah, they're just different architectural solutions, and it's the one I'm more familiar with. The earlier, the better.
Mike: [1:11:26] Do you have another way in which you would accomplish this? I'd love to hear your...
Naomi: [1:11:30] No, just through the web server itself.
Mike: [1:11:33] Cool, yeah.
Naomi: [1:11:34] Nice to see [inaudible] .
Mike: [1:11:36] Sure. If you have an [indecipherable] in front of this, an HA proxy, or any of the things that sit in front of your actual application server, any one of those is a fine place to implement this. In this example, we're doing it in the Express level, because it's the simplest way in which I could get this course to actually run on people's machines.
[1:12:05] At any point in your application architecture, the better. That's a good point, Naomi. Anyone else have any other questions about HSTS or about man-in-the-middle at all? I'm going to ask one or two more questions here, just to confirm understanding.
[1:12:39] Does anyone want to answer what HSTS does and why it is important? Preferably someone who hasn't spoken before, if you want to take a shot, or I'll take anyone willing to answer. No takers?
Audience Member: [1:13:12] It basically rewrites your request to HTTPS before it hits the server.
Mike: [1:13:20] That's right.
Audience Member: [1:13:20] If I am correct.
Mike: [1:13:22] Yep. That ensures that no request, except for the very first request, is sent over HTTPS. Based on that, what does preloading do, HSTS preloading? OK, I'll answer that one, which is that that ensures that even that first request is over HTTPS.
[1:13:51] The browser will check if your domain is in the preload list before it connects for the first time. If so, it will use HTTPS as the default protocol.
Audience Member: [1:14:04] Do all browsers check that preload list, the same list?
Mike: [1:14:08] That's a good question. I'm pretty sure they do. Let me see. Most browsers. Chrome, Firefox, Opera, Safari, IE11, and Edge all still have HTTPS preloaded lists based off the Chrome list. Hey, look at that. I got redirected to this exact same page we were just on.
[1:14:30] Yeah, they all do support a preload list. It's important to note that, again, this is on a per-browser basis. It's really duck-taped together. This is interesting, similar to source maps. The source maps specification for JavaScript is a duck-taped together solution, also non-standard. This is a non-standard solution that just happens that all the browsers support preloading.
[1:14:56] They all maintain their own lists. I'm actually shocked that IE11 has its own list. OK. That wraps up man-in-the-middle. Just to recap man-in-the-middle attacks, a man-in-the-middle attack is when a malicious actor is reading information between you and the server.
[1:15:26] A very important piece of information is the session ID that allows them to spoof and act as you. Typically, this is called session hijacking when you use a man-in-the-middle attack to steal a session ID.
[1:15:38] The way to combat that is to use HTTPS instead of HTTP. Important to note, you need to redirect HTTP to HTTPS. You need to set your cookies to only ever transmit over HTTPS by using the secure flag.
[1:15:56] Then to avoid HTTP at all, you use HSTS, and specifically, the HSTS preload list, to ensure that all requests are sent over HTTPS. At that point, you will have done what you can in a defense-in-depth way to mitigate man-in-the-middle attacks for sessional hijacking.
[1:16:23] Any final questions on man-in-the-middle session hijacking? Cool. We're at about an hour and a half. I have us scheduled for a 5-minute break now and a 15-minute break after we tackle CSERV. I'm sure people will want to take a break, but if you can write in the group chat, raise your hand, or say yes in the participants list that you would like to take a break, we will do so.
[1:17:03] If no one does, we'll...All right, good, Will wants to take a break. Good. We will take a five-minute break. Chen, we could talk a little bit about man-in-the-middle while everyone's breaking, if you want. Everybody else, we'll be back at 1:30 sharp.
[1:17:25] The sooner that you come back, the sooner that you get hear us have idle chit-chat about where we work and where we're from, and maybe a dad joke or two. Thanks.
Naomi: [1:17:38] Hey, Mike how much did we miss if we came in at 9:45?
Mike: [1:17:44] You came in right after I set up HTTPS. What we did, Naomi, during that time is we created a...What we did was open up Charles. Sorry, we reviewed the code, what the code looks like, which is mostly an implementation detail at this point.
[1:18:07] Then we saw that session ID was the thing that we needed to protect. We saw that Social Security number was the thing we needed to protect. We opened up Charles to see our vulnerable requests. We learned that session ID gets transmitted over HTTP.
[1:18:19] Then we went ahead and we did solution number two. We went ahead and implemented this thing. This gave us the ability to serve our content over HTTPS, rather than HTTP.
Naomi: [1:18:41] Sorry, what was lesson one?
Mike: [1:18:44] Lesson one was literally us doing a Charles man-in-the-middle attack. We took this request, we copied it as cURL, and we replayed that request with a hacked message. Then that gave us just proof to us that we could perform a man-in-the-middle session hijack attack.
[1:19:07] That'll be on the recording as well. You'll see it there.
Naomi: [1:19:09] Thank you.
Chen: [1:19:10] Mike, this morning...I'm sorry. Sorry, this is Chen. Mike, this morning, when I did the port 80 whatever, I was able to put up the website and all that, but when I tried to change to 443, that's when I tried to do the HTTPS, it would not pull up.
[1:19:29] What am I missing? Is something not configured properly for 443 for my computer? Would that be the issue? I change the code, like the diffs. I looked at the solution of what you did and double-checked.
Mike: [1:19:41] You should be able to go into exercise three, actually, or any of the exercises past exercise two and run sudo npm start to make sure that you didn't miss anything with the code. It really depends on what the error message might be.
Chen: [1:19:55] Could not be reached or whatever. Like the message I was getting morning when I was troubleshooting.
Mike: [1:20:00] In the browser?
Chen: [1:20:01] In the browser, yes.
Mike: [1:20:05] It could have been that you were trying to hit port 80, or HTTP, when you should be doing HTTPS. Once you're done with lesson two, the problem we reintroduced was that HTTP was now broken.
Chen: [1:20:21] OK.
Mike: [1:20:22] Does that make sense?
Chen: [1:20:24] Yeah, it does. Probably like you said, I could replay the man-in-the-middle from the beginning and then see if I can make progress offline or whatever, after this live webinar is done.
Mike: [1:20:37] I know. I've got to tell you, the lessons are, it's good instruction to be able to write this stuff, but the truth of the matter is, the value -- I think, at least -- the value you're going to get out of this whole workshop is just seeing how...
[1:20:51] Thinking like an attacker, thinking like the user. Understanding how these attacks and mitigations work is way more than writing the lines of code to accomplish it. It's unfortunate that maybe you might not have it running, but I wouldn't let that you dissuade you from the rest of the material.
Chen: [1:21:12] Got you. One last question. I know I heard it loud and clear that it needs to be HTTPS, so it's encrypted, so one does not see the session cookie or rest of the information. About that, you were saying setting the cookie flag to secure or whatever, is that different from Express to, let's say, you use some other application? What does that mean?
Mike: [1:21:37] Depending upon what language you're using, literally, what happens here is you have to write a header. Where's my network? You have to write a header that says secure. When you set the cookie, there's a flag that browsers understand called secure. It isn't specific to backend technology. It's in your server response. When you do a site cookie header, you have to do a semicolon secure.
[1:22:19] Let me just see here. Setting a secure flag on a cookie. For example in Java, it's set the cookie ID. You set the cookie. Here is the cookie's name. Here's its value and then semicolon secure. That's enough to tell the browser this is a secure cookie that you only transmitted over HTTPS.
Chen: [1:22:47] I got you. It varies from language to language so it...
Mike: [1:22:50] Yeah. Right. It varies from language to language. What the browser needs to get is always the same. The browser needs to get the name of the cookie, followed by its value, followed by a semicolon, followed by the word secure. That will tell the browser to treat it as a secure cookie.
Chen: [1:23:06] I got you.
Mike: [1:23:08] Did that answer the question?
Chen: [1:23:12] Yes, it did.
Mike: [1:23:14] Cool. I'll give one more minute before we're back at it again. Also, take note that, obviously, the answer is on OWASP. They have basically everything you need about security. That's just like the canonical authoritative source on secure application development.
Chen: [1:23:51] The tool being used to run the security test...
Mike: [1:23:55] They also put out pen testing tools to do penetration testing. They also have npm modules that do sanitization and a whole bunch of great stuff there. I highly recommend it. Cool. We're going to jump back in. Let me get us back to where we were. We've mitigated one of the three vulnerabilities I promised you that we would mitigate. We've mitigated man-in-the-middle.
[1:24:26] The next one we're going to tackle today is called CSRF. CSRF is a cross-site request forgery. Does anyone here know what CSRF is, what cross-site request forgery is and how it works? Just before we get started, if anyone would be willing to take a shot at explaining it. If the answer is nobody, that's great. Teaching you all new stuff. If anyone does know CSRF, I'd love to hear initial explanation.
Eric: [1:25:08] I think it's when you basically trick someone into clicking a link that uses their already authenticated session into doing something.
Mike: [1:25:17] That's right. That's exactly right. Thank you, Eric. What happens here is you're using your site. You're logged in. You have your session cookie, which we know is a thing that allows you to be authenticated. A hacker tricks you into visiting their site. Their site submits a form to the target victim's site.
[1:25:45] In this case, we're going to demonstrate how this attack works. The reason why this attack works is another fundamental flaw in default Internet security, which is to say that any request sent to your origin, even if it's sent from another origin, will transmit your cookies for your origin.
[1:26:07] If I submit a form from evil.com to localhost.charlesproxycom, localhost.charlesproxy.com's cookies will be sent, so I could forge any request I want to that site. The way this works is...Where am I? We're on lesson six. We have our server running. I'm an attacker. Trust me, the yellow shirt and the smile will deceive you.
[1:26:54] As an attacker, I've logged in to this website. What I want to do is I want to steal Mike Sherov's session. Mike Sherov can write, "Hello" or whatever he wants. I want to ruin Mike's reputation and say, "Mike likes bananas" even though he really doesn't like bananas.
[1:27:14] What we're going to try to do here is we're going to try to submit a CSRF attack on behalf of Mike. To Eric's point, this requires Mike to be tricked into visiting my website. I'm going to basically make a CSRF version of this form.
[1:27:31] What I'm going to do is I'm going to view the source of the page like the good old days of the Internet. I could see exactly how this form works. It's HTML form. It does a post to the root endpoint, submit some message, specify by this message text area, and has a submit button.
[1:27:57] What I'm going to do is I'm going to copy that form as a hacker. Because I'm evil, I will open up my index HTML site. I'm going to paste the form in it. This isn't good enough. I don't want the user to fill the form on my site. I want to submit the form on behalf of the user who I've tricked.
[1:28:23] First thing I want to do is I'm going to want to give this form a name. Little known fact, if you give an element an ID in HTML, then you can enscript, reference it by that ID. The browsers do that for you. The form is this form. You could also get this by doing document.getElementById theForm. That takes too long. I'm just going to say, "When this page loads, I will submit this form."
[1:29:04] If I do that, in a separate terminal, I will go to the same directory, 06. I will sudo npm start evil.com. Complicated password, typed many times. Sorry. I have to run. If I look at my evil.com site, I see that I cannot post to slash. Why can't I post to slash? What did I do wrong here?
[1:30:07] What happens is, I made a mistake, sorry. I'm submitting to evil.com/. What I should be submitting is the target website. I'm going to change the action of the form to target website. I can go back to evil.com again. It submitted an empty message. Also, we directed the victim to localhost.charlesproxy.com. That is because forms, by default when submitting, will change the URL of the browser.
[1:30:51] What I can do here is I can make a hidden iframe. I can give this a name, hidden iframe. That should be good enough. I could say my form's target is hidden iframe. Cool. I can do that. I'm using Prettier, which will autoformat my HTML.
[1:31:22] I can go back to evil.com:666/index.html. I've now submitted again an empty message. It's pretty apparent to the user that I've done something funky. I have an iframe that I'm submitting to. What I want to do is I want to hide this whole thing so I can wrap this form in a div and I could use the hidden attribute.
[1:31:55] Just in case you didn't know, hidden is the replacement for style.display=none, display:none. You could just use hidden. I can come back over here, and I could refresh again. Now, boom, I have a hidden form that autosubmits to hidden iframe, but doesn't submit anything that's damaging. Again, I really don't like bananas. I'm going to change the default value of the text area to be "I like bananas."
[1:32:26] I can, once again, refresh this page. You could see it's made a post request with all the information I want, I like bananas. I can go to this site and, boom, I like bananas. What's happened is Mike Sherov logged into this site. He has a session. He's then tricked into visiting the attacker's website. The attacker's website leverages the fact that he already has a session started.
[1:33:02] Because the default behavior of the Internet, of websites, and of browsers is to transmit cookies across site, I have complete control over what Mike is posting with his session ID. Again, his session ID is transmitted from evil.com. That is CSRF.
[1:33:39] Before we go into this lesson or this exercise, does anyone have any questions about what I just said about CSRF and who's playing what roles, when?
Naomi: [1:34:03] Mike, do you know of any famous hacks that happened because of CSRF?
Mike: [1:34:07] Do I know of any famous CSRF attacks? No. I don't know of any specific famous CSRF attacks. The thing about CSRF attacks is they require social engineering, to Eric's point. Someone has to be tricked. It's pretty specifically targeted to, typically, it's like officials, groups that are called APTs.
[1:34:37] Advanced persistent threats will send around the clock to senators, congressmen, presidents, and diplomats' phishing emails, and waiting for one of them to click on that thing and seeing if you could do a CSRF from there. I don't know any specific high-profile ones off the top of my head. Cool. Does that answer the question, Naomi? I assume so.
[1:35:09] Just to talk about the mechanics of this here again, I started up my victim site sudo npm start from within the 06 directory. In another terminal window, I started up with sudo npm run start:evil.com, the evil.com server. I then copy and pasted the form from this site.
[1:35:42] Over here, I changed the action to point back to the victim's site. I changed the target to point to hidden iframe. I wrapped it in a hidden div. I gave the form an ID. Then I added a script element that submits the form as soon as the page is loaded. We'll take eight minutes for this one I guess, or six minutes. We'll go to 150 on this one. As usual, the solutions are in. the solution MD file.
[1:36:24] If anyone wants to ask questions while we're working on this, feel free to ask. Also, just a reminder, the URL of the hacker's site is https://evil.com:666/index.html, which is important. You can't just leave this. Maybe it does work.
Naomi: [1:37:01] Mike, I heard back in the day, CSRF would only work if you're attacked on the same browser, the tabs within the same browser instance I guess. If you open up a new browser window, a whole separate instance of the browser executable that it will work. Have you heard of that?
Mike: [1:37:19] That's a good question. The way this works is you need to have a valid session to use [inaudible] forgery. If your session ID cookie is a session cookie, I know it's confusing terminology. Session cookie describes a lifespan of the cookie. Session ID cookie is what's inside the value of the cookie.
[1:37:46] If your session ID cookie is a session cookie, when you close the browser, it goes away. All that matters is the lifetime, how long the cookies lasts. It won't work across browsers, because Firefox and Chrome won't share cookies. It may or may not work across browser sessions depending upon how long the session ID cookie lives.
[1:38:12] There's plenty of sites that keep you logged in essentially forever even if you close the browser window. For those sites, it would survive across multiple instance of the browser being open. Good question. Does that answer it?
Naomi: [1:38:38] Yeah, thanks.
Mike: [1:38:39] Good question.