 When we think about security, it's mostly like server side, firewalls, or some injection of the server. But usually when people develop apps, especially because they do SPAs and they're doing a lot of front-end work, we usually don't think about security. And that's bad. Okay. First, let me introduce myself. I'm Rieber Bitski. I'm a co-founder of a company called Web Store in SRO, and our company helps people to bring the security of the e-commerce startups, and we're working mostly in e-commerce field. Okay. First of all, why React? So this is a survey about JavaScript world from 2018, and as you can see, React is the most adapted framework nowadays. And if you go to Medium or other web sources, you'll find out that people are talking about React a lot, but unfortunately, they're not talking too much about security in React. How to build secure apps. Let's take a look to OWASP. So OWASP is the most popular security issues, and it is recently created a new list. So as you can see, they are more or less the same, and if you take a look to front-end side, those are the two common issues, like cross-site scripting, it's like a common one in the web world, and thanks God in 2017 it's less popular. And, you know, we still use vulnerable compliance. And I think that if success issues came from line number three to number seven, because we have a lot of automated tools, like even some machine learning practices, how to prevent developers writing bad code. But we have another issue, and like broken authentication or sensitive data exposure, this is not about technology. It's more about people, and it's more about your developers. How good your code quality is, and if you think about security in advance. So let's go through this list and see how these issues can appear in your front-end SPAs in React, and how you can avoid them. So let's start with broken authentication. This is a very, very common issue, because in any application you have to log in, you have to authorize your users, and sometimes you don't think about how to do it properly. And especially in single-page applications, first of all you have to think how you're going to measure your session, how you're going to store your sessions. And there are not so many ways of doing this. The most common one is you still use cookies. So basically you authorize your user and he gets a cookie, and then you just pass this cookie all the time. But it's okay if you have one standalone modification, but if you're talking about microservices world, then you have a bunch of different services talking to each other. It's not that useful. So that's one, like GWT tokens, so like other tokens came on board, and you can store your tokens in a web browser local storage. In this case, you in your JavaScript code know what it is, and you have some payload, some data, and you can pass it to different microservices. But web storage is not that good from performance point of view. It's like synchronized calls, and it's a bit slow sometimes. Another option is you can use index DB. That's a more modern thing in the web world. So it's kind of built-in database in your web browser. It's asynchronous, so it works faster, but it has a really horrible interface. So usually you have some wrappers on top of that to make your code more or less readable. So let's talk how you can insecure cookies. First of all, when you get a cookie from a server, it has some parameters. First you must set secure flag to be true, and it means that your cookie will be passed only over HTTPS protocol, so you cannot steal it or sniff it. Then you should set the HTTP-only flag for the cookie. It means your browser from JavaScript does not have access to it, and in this way you protect from XSF attacks. The problem is if you have some payload in this cookie that you want to use in your SPA, then this approach is not going to work. This is a new flag called same-side-strict. It means if you have a cookie and if you're passing it to your secure endpoint, the cookie will be passed to the browser only to a particular domain, and in this case you avoid a CSRF attack. And all modern browsers support it, and it's highly recommended to start using it. Then you can set up expiration dates and time for your cookies as well, so please don't create long, one-year-living-life cookies, because then someone can steal them. The next approach is session management via JSON web tokens. I have to say that it's probably the most popular way how you do authentication or session management nowadays, especially in single-page applications. So this is an open standard, and it's a stateless token that uses most of authorization and information exchange if you have multiple wrestling points, and you want to pass information about your user roles or something else, you can keep it in the token. Usually tokens look like this, so it has three sections. The first section is information about what algorithm you're using and what is your signature algorithm for that, because they're signed with a private key or with your public and private key depending on your configuration. So header, it's encryption information, then you have payload, this is a gray one, and then you have your signature. You have different options how you can sign your tokens. You can use HMAC, and in this case you use one private key, because it might be shared between all your microservices. Or you can use RSA, so you just have to share your public key between all your services, not private key. So in just a few useful libraries, if you want to work with JWT tokens, then you most probably will use JSON web token and NPM package. And in case you want to create a token where your payload is encrypted, there probably are a lot of cases when you want to do that, because in this case you have to deliver your secret key to the client that's not secure. So there's a standard called GWE and GWS. In this case, there's a library to work with that. It's called NodeJaws. If you need some encryption inside JWT tokens, then you can play with it. So in WASP 2017, we have another vulnerability, insecure digitalization. It means that, let's say you have a token, and you can put some information to your payload, for example user ID. And then what happens on the server side, you send this token and you don't check your, for example, your signature, let us write out that it was used. And it means that malicious guy can just go and change the user ID and authenticate as a different user. And I honestly have seen it a few times, so it's pretty bad. And JWT token validation is vulnerable to this thing. So in the standard, they have different headers where you can specify your algorithm, you can specify your expiration or you can specify who created the token. So, for example, out is a user algorithm and it could be a symmetric or asymmetric. And then in your payload, you can specify your expiration time, your domain name, who created the token, and you can do please use token in 15 minutes or so. So to secure, the rules for validation is, first of all, whenever JWT token comes to you, make sure that a bad algorithm is used. For example, you can create a token that's algorithm equals none. It means it's not signed. And like a few years ago, it was a common security issue. So even like libraries, like why do you use libraries? They didn't check algorithm out of the box. So you can create a token with algorithm none. And then the libraries pass the validation even if they require signature. You must specify, obviously, like an expiration time. And in case of JWT, it should be as short as possible, like 10, 15 minutes maximum. And finally, this is a table where you can see different vulnerabilities and how to protect against them. So I think, since the same site cookie flag is widely adopted, I'd probably recommend to use cookies nowadays if you don't need to do something on the client side. But make sure you use the same site flag because then you're immune to SRF as well. So broken access control. That's another common family of security issues when developers just don't think about, don't check all their permissions on the client side, on the server side. In terms of React, if you check any enterprise, more as big enterprise application, you will see like spaghetti code like this. If your role is equal to this, then render something. And if you have code like this, it's really hard to maintain it. Let's say you added new security role and you have to change your interface based on that. It means you have to go through all your code and apply the fix. There's the solution for that. There's a library called Castle. So Castle is a component where you have one data store for your authorization policy. Whenever you authenticate a user, you get all his permissions and then you have like one data store and then you can have React components that will render your application based on your role. So you install it. After you install the package, you define your policy. So if you look like this, it looks like a can view all. It means the client user has redone the access to the system and nothing more. After you have the policy, you create a, as you call it, can component. The can component will look like this. So you just wrap your code, this is a can, and you specify here what action and what is your subject. So here we check if I can update a page then we end up updating. Another problem with React is, or with any SPA, that we use client-side routing. It means that we manage all the URLs in the browser. And in case of React, probably go-to solution is the React router. But React router doesn't support your authorization features out of the box. This is the code of how you can wrap your router with this can, this castle, and check your permissions. And after that, your routing will look like this. So if I can update a page, then I can go to update URL. Otherwise, your user will be redirected to login page or access denied. So sensitive data exposure. That's another new family of vulnerabilities, and the reason is developers don't, usually don't think about how they're managing encryption, how they work with encryption, or, for example, as we saw in the previous talk, what data we're going to expose to public. Okay, so in case of any web development, please make sure that you use the S7T web encryption nowadays. And now you don't need to pay for the Azure certificate. Just go and use web encryption. And if you're talking about client-side, modern browsers are smart enough to encrypt the data on the client. So there is W2G, W3C standards called web-cryptor APIs. So it provides you symmetric and asymptomatic encryption. So you can do RSAs, elliptic curves, or IS encryption on the client. And if you have to deal with elder browsers, you can use Stanford Library. And I did some performance testing. It's quite good, it's quite performant, especially if you're running it on Node.js. It provides you almost the same performance as OpenSL, built-in encryption algorithms. Okay, cross-stitching is a lovely one that is still alive, unfortunately. That's a big, like, long topic, and you can talk a few hours how you can hack, react, because it's not that secure, as we may think of. But let's concentrate on how we can prevent our developers writing bad code and preventing XSS. If you create your application using a React app, this is like a go-to solution for React, then it will bring ESLint by default. This is a list of plugins that it can help you. There's a plugin for XSS. There's a plugin that will check the security, some common security issues, and... Markdown React, so... Markdown here, because, you know, sometimes developers think, okay, I'm not going to write any JavaScript code or HTML code on my front-end. I will just get a Markdown file, Markdown is just text, it's on HTML, so I'm secure. Unfortunately, that's not the case, and I saw some examples, because Markdown is converted to your HTML anyway, and whenever Markdown is rendered in React, usually it does not apply HTML encoding, so it means whatever is rendered as a Markdown rendered output will go to your browser. And you can add some malicious JavaScript and malicious code into Markdown as well. And this is another sample that I've seen in real-life projects when you have malicious code coming from Markdown rendered on the browser. Using components with non-vulnerabilities. Okay, so it's 2019, so the good news are we have tools that can audit all the systems, and after recent security problems in NPM when some modules were hacked and some platform was added to them, NPM came with this tool called NPM Audit. So whenever you do NPM install, NPM itself will check all your dependencies against security database and let you know if something is broken or not. And they also are trying to fix it if you run NPM Audit fix. If it's possible to fix, if the fixed version is just a minor change for the library you're using, then it will apply the changes. Otherwise you have to do it manually. And there's another product called SNCC. It's also quite popular, and it's not just about JavaScript, it's also, I think, they do at Ruby and PHP as well. So it's a big, giant database of vulnerable components. And you can check your code against it. So it was like a really short, brief introduction about what you can do right now to make your React application secure. As a summary, I would suggest you, first of all, think about risk management because security is also all about risk management. If you have your website where you just post your cat photos, then probably you're not going to spend like a few hundred thousand dollars on security. But if you're building a big e-commerce portal, then you have to think about security a lot, and you have to have a budget for that. Also, please invest in security training for developers because, as you can see, the common issues are not because of tools, but because of developers. Because developers don't think about how the application might be hacked, and probably they even don't know how the application might be hacked. So education, I think, is very important. Also, if you can avoid writing code related to security, please do it. If there is a component, just use it because most of these components came from security companies and they audited and probably the security companies know what they're writing. And yeah, don't trust any input. Here I'm just talking about the user input, also from the database. For example, there was a case when the markdown came from a third-party system and it came to the database and then it was rendered on the website. And in this data stream was some malicious code. Basically, yeah, you never know where you can get the malicious input. And yeah, try to automate as much as you can. Use tools automation. That's it. Thank you. Very, very short introduction.