Cross Site Request Funkery Securing Your Angular Apps From Evil Doers | Dave Smith

Cross Site Request Funkery   Securing Your Angular Apps From Evil Doers | Dave Smith


>>Hello. How is everybody? Are you ready to fall asleep after eating
lunch? Because I am one of the world’s leading security
experts. That is utterly untrue. I’m going to talk to you today about cross
site request forgery, but since our theme is ’80s, it has to be funkery, you can follow
me on Twitter. This is my beautiful family on the left-hand
side, I have five children. That’s how much I value security. I have quinttuplet redundancy. The picture on the right-hand side is my father
and I completing a bike race with matching socks. More about me, I’m a panelist on the JavaScript
podcast, I’m cohost of the soft skills engineering podcast, which we launched this year. Any listeners? One, two. Great. I’m the engineering director at a call called
higher view base in Salt Lake City, Utah in the USA. As you know automate a leading expert in security,
I actually have a very real degree from a university named here with a doctorate in
CSRF, so that’s what qualifies me to talk to you today, and it definitely was not generated
from fake diploma.ko.uk. I just want you to know that. Also, here’s a disclaimer, if you have a problem
with my talk, show me the attack vector, I’ve had many people tell me the issue with bonds. If you have an issue to say, I would love
to hear about it, but please tell me an example of it. It’s so much easier to talk concretely rather
than hands waving. I rather see the electrode. Disclaimer number two. This is going to be a very fast whirlwind
introduction to CSRF. But today, we will have office hours at 2:40
p.m., you are welcome to come and talk with me. I would love to look at your system, and maybe
we can decide whether you have a CSRF problem, or maybe you have a CS RF solution you would
like to talk about it. Come over to the room, I would love to talk
to you, and also we have a panel on security and performance in the morning at 11:45. Okay. My real qualifications to talk about this
subject is that I designed higher views, our Web platforms CSRF Web prevention over the
past five years. We’ve past four security audits with on-site
penetration testing and multiple penetration with various vendors over the years. I have successfully argued CSRF with a trained
professional. So why should you care about CSRF? The answer is this is a very subtle and easy
to mistake security problem that has plagued many companies, including ING bank that their
customers became victims of fraudulent money transfers a few years ago and YouTube fell
victim to CSRF where attackers could do almost any action on behalf of the the other user
because of the CSRF vulnerability. Here’s our agenda. We’re going to first talk about how it works,
and then we’re going to talk about how baddies exploit it and then talk about how to stop
the baddies. Three parts. First we need to talk about Web authentication. Beforehand CSRF, you have to understand how
users are authentication on the Web. Stateless, I didn’t know what it means, but
essentially what the what it means is we use cookies basically to authentic. And the reason we have to use cookies is every
single Web request must be reauthenticated even if you’re using the same connection over
and over to talk to the same Web server, it must reauthentic you for every single request. So I want to walk you through one of these
examples so that you can see how this authentication tends to work. So follow the mouse cursor here. Step one the Web browser issues a get request
to www.com and then sends cookies along, and says you don’t have a cookie, so what does
it send? The log in page. And then the browser shows that log in page
to the user, the user enters their password and then they hit submit and it posts the
log in request to the log in end point. And then takes that request and sends it to
some store back end, maybe a service, maybe a database lookup, and when it is found to
be correct, their user name and password match a known user, then it will generate a random
session identifier, which will then go back to ultimately the browser in the form of a
session cookie. In this case, it’s going to be called session
ID, different back ends will name these cookies differently, but session ID is a pretty common
one, and you can see here one, two, three, four, five is the same session ID that the
backened gave. The browser then stores that cookie on the
user’s computer in persistent storage. And the next time they try to get WW.example.com,
it gets a request that says my session ID equals 12345, the session doesn’t know that
this is the same person who made the last question request, so it has to check back
in, and it says who is 12345? The session says that’s Bob, and then serves
the home page customized for Bob. A couple of things to know on this diagram. The first one is that the session ID is set
as a cookie in the response header from the Web server. And once the browser gets that response header
cookie, it will then store it for future use and then the next request, the browser sends
that same value back to the server. Okay? This is just Web fundamentals, authentication
101. All right. So cookie privacy. Browsers are actually responsible for preventing
websites from accessing each other’s cookies. The last thing we would want is for you to
log into a bank and then have one cookie and then go log into Facebook and give that same
cookie to Facebook, now Facebook can go log in as you as your bank. We wouldn’t want that. So cookies are scoped by host among other
things, which prevents browsers — or browsers then prevent users from seeing cookies across
hosts. I said users, what they prevent is servers
from seeing cookies that belong to other hosts. They enforce this, it’s their job. What this means is that if I ever a baddie
site.com that wants to do bad things to me, it cannot read my cookies from mycompany.com. It just can’t. Browsers will not send that cookie to mycompany.com. But — and this is where cross site forgery
comes in. Everything I’ve said up to this point is just
introduction and background. But they’ve been servers can’t see cookies
from each other, browsers love to send cookies to the website that issued them. They love to do cross site request forgery,
which means that if, for example, I am a bad evil doer, and I create a website called www.baddiesite.com,
and I put this HTML, which I’ll show you in a minute, and if I can trick a user to go
to this page, I can trick the user to go to their own website with their session if they
have one and do bad things with their account. So let’s do this. All I’ve done is create a simple form with
a post, and the action is HTTPS my app.com, delete my whole account. Okay? Just like that. That’s something you guys have all implemented,
I’m sure. And then a script tag down here, as soon as
the page loads, it finds that form, it’s the only form on the page, societies index zero,
and it calls submit. So what does the browser do when I feed this
HTML to you? You’ll see a blank page for a brief moment. And the next thing you know, the browser does
a post over to myapp.com and even though baddiesite.com is currently serving the page, the browser
will happily send all the cookies from myapp.com over. Including the session cookie. So now continuance I have just requested to
delete my whole account. Okay? Does that make sense? So there’s a little bit of trickery involved
here, a bad guy has to actually trick a user going to baddiesite.com. But once they do, CSRF takes over and the
browser happily submits that request to that website. All right. So that is CSRF, and I want to show you what
that looks like visually. So imagine here’s Chrome, and, by the way,
this affects all browsers. Browsers do this because this is what the
Web specification says to do. This is not a vulnerability. This is by design. Imagine you’re with Chrome, and you have your
Internet cloud. You have my app.com and baddiesite.com. Chrome will go and assuming previously that
you were logged into my app.com, that is a precondition, and that you currently have
a valid session with myapp.com, which is a very common thing to do, especially myapp.com. Great website. You guys go there a lot? No? Okay. Maybe I’m the only one. So you get this evil HTML, and then it responds
with it, and then your browser immediately does that post back to that form. And the next thing you know, it’s passing
along that cookie with that session ID and boom my account just got deleted just like
that. Bye-bye. That’s how it works. That’s how CSRF happens. Now I want to show you that in action. So I’ve prepared a small CSRF Web server,
I’m going to show you the code, and then we’re going to fix it to make it not CSRF vulnerable,
and we’ll do the exploit, and I’ll show you it working. So I have here a fake bank website, it’s the
world’s least secure bank, it also cannot store any money, which is great. But it has this end point called slash money
slash transfer. And if you are logged in, then it will do
a pretend transfer to whatever account you specify in the post body. And in the amount of whatever amount is specified
in the post body. And that’s what it will do. So you can see it’s not actually doing a real
transfer, but just for the purposes of demonstration, you can see that this is how it would happen. Okay? That’s how that happens. I’ve also got, you know, a very basic page
here that has a log in form and some other stuff. So let’s go look at this running. So here’s my very real bank. I am not currently logged in, so let’s go
ahead and log in. And I’ll just type in my user name, which
is Dave, and my super secure password, and now I’m going to log in. And now you can see I’m at the same website,
but this time, my session told it that I’m logged in as Dave. Okay? So now I have a cookie. And if we were to go look in our application
tab of the Chrome inspector, you can see I actually have a session ID right here. See the value is this randomly generated string,
that’s my session ID. On the back end in the Web server side, it
uses that session ID to look up my name, and it finds that my name is Dave. Okay? All right. Now, I’m going to show you another website
that I have built called badguyswebsite. And it’s just a simple index.HTML with an
I frame in it that points to I frame.HTML, now, they’re not to do CSRF, but it makes
things easier to see what’s happening if I put an I frame in there. So I’m going to show you the contents of the
I frame now. And this should look pretty familiar. This is very similar to the example I showed
a minute ago. It’s a post form that goes to my veryrealbank.com/money/transfer,
it has two hidden inputs, an account, an amount, and the amount is the amount I specified,
let’s pretend this is my bank account because I want to steal your money. And here’s an amount of money that looks to
be very large, which in this case of my bank account would fail because of insufficient
funds but in the case of this rich person who we’re attacking, it would do just fine,
but here we can see it happening. So in this website, I have actually deployed
two fire bays, and I’m just going to do a refresh here, and you’ll watch the website
come up and — must be logged in. Maybe I’m not logged in. Oh, right. Because I restarted my server. Sorry. Let me log in again. Go over to baddiewebsite and refresh. Success. Okay. So what just happened here is that I am on
this website called CSRF example.firebaseapp.com. And inside is a I frame that did a simple
form post, but not to the same site. To the cross site. It went to my very real bank.com and executed
a money transfer. The same money transfer that I could execute
here on the bank website, I can also execute from any I frame on the Internet. Okay. So that is how CSRF exploit works. So to fix this, we need to figure out a way
to identify the sending browser. And the way that we do that — one way to
do that is to use a middle wear called C surf, which is express middle wear, and it uses
cookies, so I’m going to download this and install that middle ware and now what’s going
to happen is that the middle ware on this end point will require that any post request
be accompanied by a cookie whose name is underscore CSRF and a matching form value or header whose
name is also underscore CSRF and has the same value. And I’ll talk about that in a little bit more
in a few minutes. But now if I go over to this website, and
I refresh, it just says forbidden. Because that middle ware identified that this
website can’t possibly be from the same place as the website that I’m actually meaning to
host. It must be from a third party, and therefore,
we forbid it. Okay. So that’s the demo. Let’s talk about what just happened there. So before — so I think I already explained
kind of the process there. We’re going to go into the details about the
cookies and the headers and all of that stuff in a minute. But I want to very quickly dispel myths about
CSRF. You may think you’re protected from CSRF by
virtue of some other factor in your app. But you might be wrong. For example, a session cookie marked with
the secure flag is — will protect you from CSRF. This is not true. In fact, it doesn’t matter whether it’s secure
or not. HTTPS protects me, this is also not true. You may have seen in my example both of those
websites were HTTPS. It does not help. You might have think having an HTTP only session
cookie which accessed by JavaScript might help, not true, there was no JavaScript involved
in the request at all. The only JavaScript on the page was the form
submit call, but other than that, a regular HTTP request. You may think JSON APIs are not vulnerable. Are these all form posts; right? Well, that is also not true, and I’ll show
you a very clever example of someone exploiting an API using clever form inputs. And you may think I only do things with rest,
and therefore all the things that could alter data from my users must be a delete or example. That also won’t protect you because while
it’s true HTML forms can’t do deletes, they can do posts, which could have harmful side
effects. So five myths busted. I’m going to do into that JSON thing really
quickly here, it turns out you can validate JSON payloads from an HTML form using form
encoding with some very clever placement of single quotes and double quotes. You can see how I have a hidden input whose
name is the beginning of some JSON and the value is the end of the JSON, including this
curly brace, and this results in a valid JSON objecting posted to the server. Isn’t that clever? Notice the equal sign that slipped in here. Still valid JSON. So some researchers figured this out back
in 2012, and it means that your JSON APIs are not safe. So thanks, researchers. Also, in the future JSON forms might become
a thing where you can actually have an encoding of JSON instead of form encoding. So how do we stop them? The answer is we can only accept requests
from pages we trust, and how do we establish trust? The answer to that is you must work with your
back end people to come up with a scheme. You must have love between front-end and back
end. You cannot do this alone. Neither back end nor front-end can do this
without each other. If you read the Angular 2 documentation on
XRF, provided it has the right names for its cookies and right techniques, which you can
read down here. Let me break down the responsibility for the
server side and client server side. On the server, you must know that it must
reject any mismatched cookie and header. Or it doesn’t have the header at all. It must send a randomly generated CSRF cookie
to the client, and it cannot be HTTP only for Angular. You also need to use cores, by Ajax, which
usually is in default, and any time you want to make an Ajax request, you send a matching
header whose value matches that same cookie value. Angular 1.2 and above do this for you. And the header they use is called XSRF token,
and the cookie is called XSRF token. Here’s the cookie for that, you can see every
time a request is sent, it says T sees if it’s the same origin and grabs the cookie
and includes it in the header. And does the same thing, it uses something
called a strategy, and I won’t bore you with all the details there. Here’s what the request looks like. Here’s an Ajax request to an end point. So XSRF token, whose value is a randomly generated
string, that is a cookie value called XSRF token, the request also includes a header
with the same randomly generated value and this two must match, so the server can trust
this. However, if the server gets a request that
looks like this, it knows that it cannot be trusted. It may have come from a nontrusted third party
domain because it is missing the header. And and remember, HTML forms, they cannot
submit headers, and that’s why this works. So from the attackers perspective, they can
cross the the form post payload, they can write whatever they want in the HTML, they
can even control the content type in the limits, there’s a couple of different values they
can choose from. They can also control the method from the
get post request. But they can’t control headers, they can’t
set them, read them, and they cannot control cookies. Because they’re running on a different domain,
they don’t have access to the cookies, all they can do is rely on the browser to forward
the cookies. The good news is there’s hope for a brighter
future. Right now we have to do these gyrations and
dance around cookies and headers, but there’s a new spec that’s in draft right now to do
something called same site cookies. This is a browser feature similar to HSTS
where — similar in spirit anyway, where you can give a browser a cookie and tell it do
not ever forward this cookie from across site requests. Only send it to me if it’s coming from the
same domain that issued it. And once that’s in place, this whole mess
will go away. This whole mess has been around for a decade. So it’s called same site, and it will really
help a lot once browsers adopt it. In the meantime, we’re going to have to continue
keep jumping through cookies and headers and all kinds of stuff. So in conclusion, you have to stop
the hackers. I’m just waiting for the giggles. Who saw the banana? Anyone see the banana? There you go. So I want to remind you, I’ll be available
for office hours. One of my favorite things in the world is
to talk to other developers about CSRF, I don’t know why this is fun for me, but it
is, come talk to me, we can talk to your stack and see if you have a CSRF problem, and I
would love to talk to you about that, so thank you very much for your time. [Applause]

Author: Kevin Mason

5 thoughts on “Cross Site Request Funkery Securing Your Angular Apps From Evil Doers | Dave Smith

  1. Why the CORS protection is not enought ? Should it had block the post request in you example ?
    Other question : If my client is not on the same domaine of my server, could angular2 make crsf works ? not sure it could read the cookie event with cors allows headers.

Leave a Reply

Your email address will not be published. Required fields are marked *