Security of JavaScript Applications
JavaScript is the most popular language if we talk about web development. The obvious consequence of such state of affairs is that there are dozens of attacking techniques that utilize the vulnerabilities of this programming language. In this article, we’ll consider some common security issues that should be kept in mind by every JavaScript developer.
The article is prepared by DHTMLX Team, the developers of javascript ui libraries (ui components, gantt charts, calendars, diagrams, etc.)
Cross-Site Scripting (XSS)
Cross-Site Scripting is a commonly used technique that allows running external JavaScript in the context of the attacked website. XSS allows getting access to full Web API. The simplest example of XSS attack implies that a hacker finds a vulnerable input field on the page and creates a link that injects a snipper to another page. After the link is opened by a user, it’s up to the hacker what will be happened next.
XSS is a high-rated security vulnerability since the attacker can get access to LocalStorage, SessionStorage, or cookies. That’s why it’s recommended not to store any sensitive data in these storages.
To protect your users against XSS, make sure that you never inject unknown user input into the page. Remember to use the escape syntax for those parts of the HTML document that you’re putting untrusted data. Use HTML and JavaScript escapes before putting untrusted data into HTML and JavaScript data values. Besides that don’t forget to use CSS escape. It’s recommended to avoid using sources to get rid of JavaScript security issues.
Cross-Site Request Forgery (CSRF)
CSRF is an attack that exploits the mechanism of sending HTTP requests from the browser. If a user’s PC stores some cookies from a particular website, these cookies will be sent with the request, and it doesn’t matter who starts a given request. Thus, if you let things slide and don’t defend your web app against CSRF, a hacker can steal the accounts of your users.
A simple example of CSRF attack implies that a hacker finds an unprotected <form> element on the web page. Then, a custom URL that calls the action of the given form can be created. For example, it can update the email address of your user. The hacker can request a password reminder and take over the account.
To avoid such issues, you can add a CSRF token to the form. This token should be unique per session and generated by a secure random number generator. After you generate this token, you can add it as a hidden input field in the form on your web page. The next step is to make your server reject the request action in case if the token isn’t validated.
Server-side JavaScript Injection (SSJI)
Server-side JavaScript Injection is one of the most widespread web app vulnerabilities on the web nowadays. It’s a pretty common thing when a developer accidentally introduces proneness into his web application by simple misconfiguration. For example, the eval function can be pretty open for attacks and can be exploited with ease.
You should avoid the use of the eval function to decrease the risk of such vulnerabilities. It’s used mostly for speed benefits, but it can compile and execute any JavaScript code which significantly increases the risks.
If you use the concatenation of string of unsanctioned dynamic user input, be prepared to meet some unpleasant consequences. We’re talking about the high risk of vulnerabilities. Besides that, remember that if user’s input is required for a server-side command, then it should be properly validated.
Choose Wisely Between JWT-based and Session-based Authentication
JSON Web Tokens (JWT) is a method for representing claims securely between two parties. It includes some data on the user side (e.g., name and email) along with other two values: iat (issued at) and exp (expires at). These tokens are signed by a secret key, but you should not use any sensitive data in JWSs since payloads are not encrypted. Each token consists of three base64-encoded parts that describe the used algorithm, contain the actual payload, and the signature. This technique is usually used for authenticating in SPAs and can simplify how you authenticate against different APIs hosted on different subdomains.
You have to store JWTs somewhere. In most cases, they’re stored in local storage or session storage. Such approach is potentially vulnerable to XSS attacks. Therefore, if we speak about security and authentication, you should prefer with session-based authentication. In such case, all cookies will be protected from JavaScript access by the HttpOnly flag. Besides that, cookies are much smaller which can be helpful in case of mobile applications with no access to broadband internet. JWTs can be used in case if they’re used for a short amount of time. For example, to authenticate a site on a subdomain or download some files.
Pay Due Attention to the Safety of Your Passwords
If you’re a beginner, take it as a rule that passwords should never be stored in plain text. Besides that, don’t forget to use salt, Without it, a hacker can use so-called Rainbow tables to reverse the passwords. Functions such as Bcrypt allows adding salt to your passwords. Bcrypt has an implementation for Node.js apps, so if you use it, spend some time to learn how this function works.
If we talk about handling secrets such as database passwords, don’t ever check them into your Version Control System (VCS) as plain text. To store such precious info in VCS, you can encrypt them using such apps as git-crypt or git-secret. Another handy tool is Vault. It allows to store and control access to your tokens, passwords, and other secret data.
Feel free to share your thoughts and experience in the comments.