DEV Community

loading...

⚔️🔰JavaScript Security🛡️⚔️

devpato profile image Pato Updated on ・5 min read

Security Details In Your Code

When someone visits your website, your JavaScript code runs in their browser which, at the end of the day, they have access to read your JavaScript code. Therefore if you have any sensitive data, your code will be exposing this data that can be potentially be seen by anyone.

For example:

Never allow your code to contain the admin password ... or any password somewhere in your JS code.

If someone wants to see your code, all they have to do is go to the dev tools on their browser, click on sources, then click the JS file. Sometimes if they are using webpack or a similar tool, the code generated by webpack will be at the top and the human readable code will be at the bottom.

Alt Text

In some cases they will see a "one liner" piece of code but the only thing people have to do to make it easier to read, is to go to a javascript formatter tool online and paste it then boom! Easy to read!

On the other hand, there are some API that helps us avoid exposing our API keys. Some of those API allow you to restrict the usage of the API key based on IPs, domain name, and so on. Another way to avoid sharing some security credentials is by the use of environment variables and if, for whatever reason, you need to have some sensitive data on your code, I suggest you to have it on your server side code like NodeJS.

😨 Cross-Site Scripting Attacks aka XSS 😱

I don't know about you but just by hearing XSS attacks! I'm already terrified.

This attack only applies to the front-end side. I'm not saying backend can't not be vulnerable, it can be, but not for XSS attacks.

This attack is when 👹 malicious JavaScript gets injected and executed.

So basically, the way it works is if someone is able to inject some code into your application, it can do a lot of things. Think about it as if you go to Google or an airline page and they gather a lot information from JavaScript by accessing the local storage and more.

Thanks to the security gurus, the newer browsers help with this by blocking tags being executed in our innerHTML. Yes, you can still inject but it won't be run.

BUT!! There's always a BUT. If you use a tag by injecting via the innerHTML you can do the following:

<img src="" onerror="alert('xss')/>
Enter fullscreen mode Exit fullscreen mode

So when the code executes, it will look for an image source. Since it doesn't have one, it will show the alert().

You can avoid this by instead of using innerHTML. You use textContent. But sometimes you may actually need innerHTML. If that is the case, you need to sanitize your code before it gets rendered. You can do so by using a very cool NPM package called sanitize-html. This package will "clean" your text and remove any unwanted tags so that no malicious code gets executed. You should also do some sanitation on your server side. I could stare a malicious code when entering information in a form and this code will be stored in the DB. Once it gets rendered, it can get executed. You should use this NPM package in your server before it hits the database.

Third Party Libraries

When using a 3rd party library, you have to ensure that they are secure. Sometimes the number of downloads or the stars on github doesn't mean this is a secure library.

Check out this article about a very interesting story on how someone used an NPM package to steal cryptos.

NPM helps a little with this by running a vulnerability scan when installing a package. Note: not all the vulnerabilities are bad! Do some research before freaking out.

Cross Site Request Forgery aka CSRF

This kind of attack is when people trick you into clicking on a link that leads to a prepared page where they abuse your local cookies to then send a request to the page you would normally talk to as well.

This is more of a service side issue but it is important to mention. Imagine:

For example you can be going to "x" website and they steal some of your information from your local storage. Then they re-direct you to a fake website; for example: let's say a paypal looking site. With the information they got from your local storage, they can manipulate this to send money to someone you didn't want to send money to. It can be a long process for the hacker but it can be done.

This attack not only applies to NodeJS or JavaScript technologies, it applies to web development in general.

Can CSRF be prevented? Yes.

There are 3 techniques to prevent CSRF attacks.

  1. Using the same site cookies method: This is a newly developed attribute that can be added to your cookies to instruct the browser not to allow third-party usage for specific cookies. This attribute is set by the server while at the same time setting the cookie itself.

  2. Challenge Response: As an additional layer of protection, you can require a challenge response from a user when a form is submitted. Some examples of challenge responses include:

-CAPTCHA validation (very popular)
-Asking again for Authentication of password or some personal information
-Issue a one-time token

Note: For applications in need of high security, both tokens and challenge-response should be used to ensure security.

3.Anti CSRF token: When a user submits information, interacts with the site, or does anything else that generates a cookie, the anti-CSRF token should also be included with the cookie request. This request then gets run through a verification process wherein the authenticity or even existence of this token is verified before processing the request. If the token is missing or incorrect, the request can be rejected.

Cross-Origin Resource Sharing aka the annoying CORS 😅

The concept of this is requests from your browser side application can only be made to a backend that runs on the same server.

If, by any reason, you host your frontend and your backend in different servers, you will have this issue but you can fix this by specifying headers in the response. This is a concept where, by default, browsers would not allow you to "talk" to other servers but with the right server side headers, you can override this. You can make use of the cors NPM package or by doing it manually for example:

Node.JS Code

app.use(function(req, res, next) {
  res.header("Access-Control-Allow-Origin", "*");
  res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
  res.json({data: [1,2,3,4]})
});
Enter fullscreen mode Exit fullscreen mode

Note: The CORS concept applies to any web application that has code that tries to interact with frontend and backend. Doesn't matter if its nodejs, php, or whatever.

Discussion

pic
Editor guide