Video Summary and Transcription
Handling security in front-end development is crucial, and the OWASP Top 10 is a valuable resource for secure coding. The list of security risks is constantly evolving, and the Nuxt security module provides features like security headers, rate limiting, and cross-site request forgery protection. Frontend developers should prioritize security to avoid information leaks and mitigate risks. Understanding the difference between public and private tokens is important for secure token handling.
1. Introduction to Secure Next Apps
Handling security is traditionally seen as the responsibility of back-end developers or DevOps engineers. However, with more functionality being moved to the front-end, it is important for everyone to prioritize security. In this presentation, I will discuss more secure Next apps by default and raise awareness about security risks in modern web applications. One crucial resource is OWASP Top 10, a document that highlights the most critical security risks. It is recognized as the first step towards more secure coding. The list of security risks is constantly evolving, as seen on the OWASP Top 10 website.
Hi there. I always thought that handling security should be a responsibility of back-end developers or DevOps engineers. But nowadays, more and more functionality is being forwarded to the front-end. And that is why I believe that everyone should be taking care of security. And that is also why I have selected this topic for my today's presentation, which is more secure Next apps by default.
My name is Jakub and I work at Allokai as a senior developer and advocate. Apart from that, I'm also a Google developer expert in web performance. I am part of the Next team and I'm also an ambassador for Algolia, Storyblok, Cloudinary, and SuperBase. So, after this presentation, you will be a security ninja. That sounds great, right? But the reality is that it is not possible. It is not possible to transfer to you all the security knowledge that is necessary to build secure applications out of the box. So, my idea is to make you more aware of security risks and issues that can appear in modern web applications. Because I believe that if you are aware of these issues, you will be able to protect your application against them.
So, for that, I would recommend you to become familiar with the concept of OWASP and specifically OWASP Top 10. So, OWASP is a standard awareness document for both developers and web security, web application security specialists, and it represents broad consensus about the most critical security risks to web applications. And as you can see, I marked two places here. One is standard awareness document, which basically means that this OWASP Top 10 is a document. And the second one, security risks. So, it is a document that will showcase to you the most popular security risks. OWASP Top 10 is also recognized by developers as the first step towards more secure coding. This time as well, marked with green color, first step.
So, if you look at the OWASP Top 10 website, you will see basically this. And if we zoom in a bit, we will see this list of most popular security risks that can appear in your web application. And as you can see on the left side, we have 2017, and on the right side, there's 2021. And you see that the list, both the order and the elements of the list are changing. Which means that this list is evolving over and over. Like all the time.
2. Overview of Security Risks
The list of security risks is constantly evolving, as new issues and risks emerge. OWASP's website provides a wealth of knowledge, including checklists and cheat sheets for different application types. We'll focus on a few selected risks, such as cross-site scripting and SQL injections. Broken access control can allow unauthorized access to sensitive data. DOS and DDOS attacks can overwhelm an application's server, causing it to become unresponsive. Additionally, malicious NPM packages and dependency confusion pose a significant threat to web applications.
And you see that the list, both the order and the elements of the list are changing. Which means that this list is evolving over and over. Like all the time. Because new issues or new risks are appearing and we have to make our apps more and more secure based on changing environments.
And there is also a big, very big resource of knowledge in terms of making your app more secure on OWASP's website, which is basically a list of checklists, like cheat sheets, that you can review to see if your application is secure in a certain area. So, for example, we have cheat sheet for REST applications, GraphQL applications, applications built with Ruby and so on and so on.
So, let's take a look at some of these security risks. We won't be taking a look at all of them, we'll be focusing only on a few selected ones. So, first of all, we have injections. And the two main attacks here, or risks, are cross-site scripting and SQL injections. And in terms of SQL injections, you might think that this is a very old vulnerability and it doesn't appear anymore, but you would be surprised how many production websites have this kind of vulnerability still.
In both cases, the idea is that the attacker is injecting some kind of malicious code in either SQL, so our database, or in the applications through JavaScript, for example, and then this malicious code is basically getting the data getting the shouldn't have access to, like users, passwords, stuff like that. Going further, we have broken access control. Access control means that our application will allow to get certain data if we are properly authorized.
So, for example, we are logged in, or we are part of organization, or group, that has access to certain resource. So, broken access control means that the attacker can have access to the data that basically he or she shouldn't have. And my favorite one, which is DOS, or DDOS, which means denial of service, means that our application is served on a server that can serve or handle only a certain amount of requests. So, if attacker manages to send too many requests, our application won't be able to serve the responses to these requests and basically give up.
So, we have DOS, which is denial of service, and DDOS, which is like the distributed denial of service, which is the routing is basically distributed between many different so-called zombie devices. It can be mobile phones, it can be desktop devices, and so on and so on. And I have one interesting bonus case, which is called malicious NPM packages and dependency confusion. This can happen for anyone who is building web applications nowadays.
So, how it works is basically we have a user that is supposed to fetch a package that is stored in a private registry. Like private NPM registry. It could be something else. The idea is that this registry is like a private one, and only authorized users should have access to it, should be able to fetch this package. So, what the user does instead unintentionally is to fetch the package with the same name, but from the public registry, like the public NPM. And this package can contain a malicious code. And this is a real case. And this is, unfortunately, this is in Polish.
3. Securing Applications with HTTP Security Headers
The author of a malicious NPM package targeted big companies like PayPal, Microsoft, Apple, Shopify, Netflix, Tesla, and Uber, using a reverse shell to gain remote access to devices. A bounty of $130,000 was awarded. Securing applications can be enhanced with native browser APIs, such as HTTP security headers, which inform the browser of restrictions and resource origins. HTTP AQUIF can be used in static applications to emulate server response headers, while browser permissions help disable certain APIs on the client side.
The article is in Polish, but you can search for the ones in English for malicious NPM packages. So, in this case, what the bounty was, because there are some, there are these challenges for ethical hackers, that you can basically detect the vulnerabilities and get bounties, like rewards for it. So, the author of this attack managed to create these packages for very popular big companies, companies like PayPal, Microsoft, Apple, Shopify, Netflix, Tesla, or Uber. So, big ones. And this code, what it was doing, it was doing something what is called reverse shell. And this reverse shell was basically able to do commands on your device, like remotely. So, someone could operate or do commands on your laptop or on your device remotely, completely. And the reward was about $130,000 for such a bounty. So, quite a lot of money.
In terms of securing your applications, I always say that the native browser APIs are your is your best help. So, let's start with HTTP security headers. So, how they work is basically on the server, we are sending those security response headers to inform the browser what it can do. So, in this case, for example, we can instruct it that it can work only with HTTPS, that it cannot use microphone, like all the different types of services, like a microphone, geolocation, camera, and so on and so on. And that the resources on this website, on this browser, on this particular website can only fetch resources from certain domain or origin. So, they work like this. So, we have the name of the header and the value. So, you may have heard about content security policy or XFrame options, strict transport security. There is actually quite few of them. But the idea is that we can configure them on the server to instruct the browser what it can do. But this happens or works with server applications, the applications that have a server. So, what we can do if our application is static.
So, we can use something called HTTP AQUIF. I hope I pronounced it correctly. So, what it does, we can configure it as a meta tag. So, we can do it in our static applications on the pure frontend. And we can somehow emulate the response header that could be sent from the server. In this particular example, we are emulating the content security policy header. And we are passing it to it as a content, the same value that normally would be sent from the server. We can also configure browser permissions. And these browser permissions basically allow us to disable certain APIs that can be enabled on the client side.
4. Enhancing Security with Nuxt Security Module
The server can disable geolocation access for users by sending the permission policy response header. Basic auth allows users to access a website with correct credentials. We can enhance Vue and Nuxt app security by following cheat sheets and utilizing the Nuxt security module, which configures the app to adhere to OWASP recommendations. Nuxt security provides security response headers, request size and rate limiters, cross-site scripting validation, cross-origin resource sharing, allowed HTTP methods, and cross-site request forgery protection. A demo of a simple Nuxt app shows response headers in the browser inspector.
So, in this particular case, we are showing the geolocation. So, if the server sends the response header permission policy with the value geolocation with these brackets, basically if we try to access the geolocation of the user, this is the code in the middle, we'll get the error that geolocation has been disabled in this document by permission policy.
Next, we have basic auth. So, basic auth basically allows the user to only access the website if they provide correct credentials. So, how it works is that the server sends the header www authenticate with the value basic realm and the value of this realm. And then the clients, the client that wants to authenticate needs to send an authorization header with a basic and these credentials. It's like usually user and password. And if these credentials are okay, that user can access this website. Otherwise, they will get 401 error. But please just don't use this kind of example of username and password if you are aiming to have this kind of credentials for your basic authentication. You can also just skip it. Because this doesn't protect anyone or anything.
So, how can we make Vue and Nuxt apps more secure? There are very good cheat sheets, both on Vue.js documentation website and HTML security cheat sheet, which basically lists all the things that you can do on the front end, on the client side to make your application more secure, which I highly recommend you to check. However, if we take a look at Nuxt, we have access to the Nuxt security module, which basically utilizes the OWASP and configures your app automatically so that it follows OWASP security patterns and recommendations to make your app more secure by default. And it does it by using the HTTP headers, some of the ones that I showed you already, and the middleware as well.
So, without any configuration, Nuxt security comes with security response headers that work for both SSR and SSG applications, like server side and static applications. It comes with the middleware for request size and rate limiters, which basically protects your app from too many requests and too big requests. We have access to cross-site scripting validation, which protects us from situations where someone will send malicious code through GET or POST requests. We have access to cross-origin resource sharing, which is like a course in short, where we can decide from where this application can fetch the data, from what origins. We also can use the middleware for allowed HTTP methods, where we can decide what methods are allowed for certain endpoints. So, on certain endpoints, we might want to basically just enable POST or delete or GET requests. And we also have support for cross-site request forgery protection.
So, onto the demo time. I have Nuxt application here running, which is basically like a very simple Nuxt app. It doesn't have any UI library, doesn't have any components. It is just a simple Hello World Nuxt application. So, if we inspect it in the browser, we will see this Nuxt welcome page. And now, if we inspect it, go to network and we refresh the page. In here, we will see response headers. We have connection, content length, content type, date, x powered by.
5. Configuring Nuxt Security Module
Enabling the Nuxt security module adds security headers to the response, including content security policy, cross-origin opener policy, and permissions policy. Cross-site scripting validation helps prevent malicious code injection. Configuration can be done in the Nuxt config.ts file, allowing for global and specific header settings. The module also provides rate limiting functionality.
What will happen when we enable or uncomment Nuxt security module is that when we inspect this, the same document, we will now see that the response header section is much bigger. We have security headers for a content security policy, cross-origin opener policy, permissions policy and many, many more configured for us automatically, according to OWASP recommendations. This comes by default in terms of response headers.
We also have access to the cross-site scripting validation, which basically means that if we say text and in here say script, let's say alert one, and we close it, script, like this, what will happen I forgot it needs to be a param. Is that we will get 400 butt request. This basically means that this underlying cross-site scripting validation trigger this text that we sent in this get request as a malicious code.
So, in the Nuxt config.ts file, we usually pass some configuration to either Nuxt framework or the modules that are part of our application. So, we have access to the security object where we can configure all our Nuxt security configuration. So, in here, I have access also to headers where I can say, for example, that I want X-XSS protection to be one. And if we inspect the browser, but right now without this, we will see that right now X-XSS protection is one. So, let's change it to zero. And we see that it was changed. This configuring headers like this is global. So, this means that these headers will be configured like this globally. However, with Nuxt security module, we also have access to root rules. So, what can happen is that we can do root rules, pass our root. So, let's say secret. And in here, we can say security. And the same as above, headers. And in here, we can say X-XSS protection one. This will mean that for the root with slash secret, the value of the header X-XSS protection will be set to one. And this works for all the headers, and it works for all middleware functionalities that are part of the module.
In here, what I will do is I will say rate limiter. And I will say tokens per interval. And I will set it to five. And interval, I will set it to, let's say, 10 seconds.
6. Using Rate Limiter and Conclusion
I will configure the rate limiter to allow five tokens per interval of 10 seconds. This will block excessive requests. The Nuxt security module provides additional features like ALF and cross-site request forgery. Remember that no system is unbreakable, so aim to create systems that are difficult to break. Check out Nuxt security documentation for more information.
In here, what I will do is I will say rate limiter. And I will say tokens per interval. And I will set it to five. And interval, I will set it to, let's say, 10 seconds.
So, right now what will happen is if you start to spam the refresh button here, after a few requests, we will be blocked. And we will see four to nine too many requests. Okay.
The module comes with much, much more. We have access to basic ALF, as I mentioned, the cross-site request forgery, and many, many more. So, make sure to check out Nuxt security documentation to get the best out of it.
Let me go back to the presentation. So, this is just the tip of the iceberg in terms of security patterns. And I want to tell you that there are no unbreakable systems. There are only those or those or that who are so difficult or time-consuming to break that attackers will basically give up. So, my recommendation for you is to be those systems. Be those systems that are difficult to break so that attackers will give up.
Thank you very much for being here with me. Make sure to check out Nuxt security. If there is something that you would see in the module that is missing or something could be done better or anything, just let us know through issues or discussions. We are always open for feedback. And if you would like to reach me somewhere, make sure to do so through X or DevTool. I'm there at Jacob Andrewski. I also have a YouTube channel called Jacob the same and GitHub. So, thanks for having me and enjoy the rest of the conference.
OWASP Top 10 and Frontend Security
Jacob asked a tricky question about the three most popular security issues in OWASP top 10. Broken access control, injection, and cryptographic failures are all valid answers. For tools to test Nuxt app security, try securityheaders.com and search for security header scanner. Frontend developers should be aware of security concerns to avoid information leaks and mitigate risks in modern web applications, even if they don't implement extensive security measures.
So, regarding the question you posted on the poll, it was what are the three most popular security issues in the latest edition of OWASP top 10 documents. At some point, the public was right because Jacob actually made a trick and he meant that all of those three are valid answers. At some point, we had a 50-50. But now, yeah, the people who chose broken access control are wrong, injection are wrong, and cryptographic failures are wrong because they are all those three at the same time. So, that was a trick question. But it's all right.
Let's fall back and get into some Q&As. So, from all the questions that we had, one of the most interesting ones is is there any tools to test my Nuxt app for any security issues? Sure. So, first of all, you can just type securityheaders.com. This website will allow you to audit your website for security headers and if they are passing the recommended values. So, it works similarly to Lighthouse, for example, or page speed.dev, where you input a URL you want to audit. But in that case, it is about performance. But in our case, it's about the validation of security headers. So, for sure, securityheaders.com. I don't have any more right now, but probably if you input in Google security header scanner, there might probably be even more tools that could give you the right answer. Okay. Makes sense.
Another one that we have is one of mine, but still the most voted. Do you think a frontend developer should know those security concerns at all? Yeah, I would say that it is equally important. Not in a way that as a frontend developer, you will be developing the same amount of security regulations or security protections to your application. It's more like if you are aware of security issues that can appear in modern web applications, you are less likely to leak some kind of information. It can be an access token. It can be a page that should only be available for a user that has appropriate rights.
So, I always believe that if you are aware of these issues, security issues, you are less likely to have these kinds of risks in your web application, even as a frontend developer. Because initially, when we think about frontend development, we think about styles, about HTML, maybe some kind of animations. But honestly, nowadays, more and more logic is being forwarded to the frontend. We have frameworks such as Next, where we can basically build full stack applications with it. So, considering that these frameworks are frontend first, that comes with a bit of backend as well, these frontend developers need to have this security knowledge, at least the basic one of the risks. You might not need to understand every risk and know every security and protection. But if you are aware of these risks, you're less likely to have them in your web app.
Token Handling and NUC Security
When dealing with tokens, it's important to understand the difference between public and private tokens. For NUC security and static applications, such as SSG apps, the NUC security module provides security improvements like content security policy and the ability to remove console logs. If you have any further questions, feel free to ask in Discord. Thank you for participating!
Yeah. I also usually have a lot of people on Stack Overflow asking, hey, so I have this token. What do I do with it? How do I hide it? And sometimes the tricky thing is you have public tokens and you have private ones. So, depending on that, then you need to find a way to deal with that. So, yeah, usually what I recommend to those people is just like, hey, you probably have a backend team. Just go and speak with the people there, so that way they can explain you a bit more. Because otherwise, if you take a private token with some money or like some service behind it, yeah, it can be a bit tricky.
What's about NUC security and servers, SSG apps, like Static Generator apps? Yeah, sure. So, if we think about security in general, we usually think about applications that involve some kind of a server. Because, for example, even with response headers, as its name suggests, it's like response headers. So, they need to be sent from the server to the client and the client when receives these headers, this browser then knows how to behave. But with NUC security, we also implemented it in a way that even if your application is static, like static SSG app, you still can benefit from some sort of the security improvements from the module. First of all, you get the content security policy as a HTTP EQIF, I believe I pronounce it correctly, like the meta tag. And this is one thing. And one more thing is that you also get the support of remove console loggers. This is like a small utility function that allows to basically hide the console logs, console debugs, and other console methods that you might just forget about while developing. I had situations where I maybe not leaked some information, but I left some console logs in the places where they shouldn't be.
Okay. Okay, okay. I guess that's all. Thanks very much. Again, if you have any other questions, like if they are not answered, you can go to Discord, you can ask it there. And a few speakers already gave answers on past topics. So, yeah, feel free to do the same if you really want to get the answer. So, thanks again for your participation, Jacob. I wish you an amazing day. Let's continue the conference. Thanks. See you.
Comments