https://snyk.io/wp-content/uploads/fundamentals-temp-image.png

JavaScript security

Like nearly any programming language, JavaScript is not without its share of potential security exposures. The best defense against common JavaScript security vulnerabilities is to be aware of them and implement the proper controls to reduce exposure.

JavaScript security risks include:

  • executing unintended script content,
  • intrusion using a user’s established session data,
  • user account tampering,
  • data theft via browser-side storage,
  • modification or addition of dynamically generated web page content. 

Implementing solutions that provide enhanced security for JavaScript applications and a multi-pronged approach includes:

  • awareness of best practices among developers,
  • proper auditing of application code to detect potential JavaScript security problems,
  • implementing technology to scan applications dynamically and identify potential JavaScript security vulnerabilities.

What is JavaScript security?

JavaScript—not to be confused with Java—is extremely popular for developing web applications that can be run on a mix of platforms for desktops, laptops, and mobile devices. There is an enormous community of JavaScript developers, sharing experiences with vulnerabilities, remedies, best practices in coding, and methods for improving JavaScript security.

Software vendors have also recognized these JavaScript security issues, reacting with JavaScript security scanner software and a variety of JavaScript security testing tools that make applications more secure and greatly reduce JavaScript security risks.

What are the JavaScript security issues?

JavaScript’s immense popularity is what makes web applications that leverage JavaScript a favorite target of hackers. Exploiting JavaScript vulnerabilities can manipulate data, redirect sessions, modify and steal data, and much more. Although JavaScript is typically thought of as a client-side application, JavaScript security issues can create problems on server-side environments as well.

One particular concern related to JavaScript is the way it interacts with the Document Object Model (DOM) on a web page, allowing scripts to be embedded and executed on client computers across the web.

What are the common JavaScript vulnerabilities?

Like nearly any programming language, JavaScript is not without its share of potential vulnerabilities. The best defense against common JavaScript security vulnerabilities is to be aware of them and implement the proper controls to reduce exposure.

Common JavaScript vulnerabilities are: 
1. JavaScript validation
2.  Cross-Site Scripting (XSS)
3. escape input from the user
4. validate input
5. sanitize
6. Cross-Site Request Forgery (CSRF)
7.  coding standards—JavaScript code security

1. Reliance on JavaScript validation

When you consider that JavaScript began as a client-side development language, it makes sense that utilizing JavaScript alone for validation of user-supplied data can introduce potentially invalid data to the server application. Most browsers as well as other tools on the client-side permit disabling JavaScript—essentially avoiding client-side validation. Other tools allow users to modify requests sent to the web application after it has already been processed by JavaScript validation routines. Either method would allow entry of potentially malicious or unverified data to the server.

Without additional server-side validation, stored data could be corrupted or replaced with erroneous data.

Repair: Implement dual validation by utilizing JavaScript validation on the client, backed up by validation on the server. With this approach, you reduce the potential for bad data, while still providing the validation functions on the client that improve results for the end-user. Server-only validation can be a nuisance to the user by requiring multiple iterations in filling out online forms before all validations are passed. JavaScript validation should be used to inform the user immediately of issues with their input while server validation ensures only expected data makes its way to the application.

2. Cross-Site Scripting (XSS)

XSS is a common vulnerability for client-side browser-driven applications. These attacks involve the injection of malware into an application, which then compromises JavaScript and HTML to execute the code. This makes the end-user the victim that facilitates the attack simply by running the application, with the malicious code appearing to be part of the web page.

Repair: Defense against XSS can be approached in several ways. Ultimately the best approach is a combination of the following:

Escape input from the user

XSS attacks rely on supplying data that contains certain special characters that are used in the underlying HTML, JavaScript, or CSS of a web page. When the browser is rendering the web page and encounters these characters, it sees them as part of the code of the web page rather than a value to be displayed. This is what allows the attacker to break-out of a text field and supply additional browser-side code that gets executed.

To prevent this, any time browser-supplied data is going to be returned in a response (whether immediately reflected or retrieved from a database), these special characters should be replaced with escape codes for those characters. For instance, the < and > characters used to delimit HTML entities can be replaced with < and > which tells the browser to display those characters rather than interpret them as HTML entities. If the browser-supplied data is being returned in a JavaScript context, non-alphanumeric characters should be escaped using \xNN where NN is the hexadecimal ASCII value of the character.

Validate input 

Wherever possible, browser-supplied input should be validated to ensure it only contains expected characters. For instance, phone number fields should only be permitted to contain numbers and perhaps a dash or parentheses characters. Input containing characters outside the expected set should be immediately rejected. These filters should be set up to look for acceptable characters and reject everything else.

Sanitize input

In some cases, it might be preferable to simply remove dangerous characters from the data received as input. This can provide some degree of protection but should not be relied on as sole protection from data manipulation. There are various techniques attackers can use to evade such filters. 

Use safe methods for manipulating the DOM

Client-side script sometimes modifies elements in the DOM directly. Methods such as innerHTML are very powerful and potentially dangerous as they don’t limit or escape the values that are passed to them. Using a method like innerText instead provides inherent escaping of potentially hazardous content. This is particularly useful in preventing DOM-based XSS attacks.

3. Sensitive cookie exposure

Client-side browser script can be very powerful in that it has access to all the content returned by a web application to the browser. This includes cookies that could potentially contain sensitive data including user session IDs. In fact, a common exploit of XSS attacks is to send the user’s session ID tokens to the attacker so they can hijack the session. 

Repair: To prevent this, most browsers now support the HTTP-Only attribute on cookies. When the server sets a cookie on the browser, setting the HTTP-Only attribute tells the browser not to allow access to the cookie from the DOM. This prevents client-side script-based attacks from accessing the sensitive data stored in those cookies. 

4. Coding standards – JavaScript code security

JavaScript developers may conceivably include hard-coded values for critical content or API keys, which could be intercepted by cyber thieves, creating a potential security risk.

Repair: Set clear standards for JavaScript coding that highlight poor or risky practices. Implement source scanning routines that seek out such code, so that it can be addressed immediately.

How to deal with JavaScript security issues?

Protecting applications and servers from JavaScript vulnerabilities can be managed through the adoption of JavaScript security best practices and the use of sophisticated scanning tools.

Ensure that all developers are aware of and follow JavaScript coding best practices:

  • avoid eval()—don’t utilize this command in code. There are better and more secure options.
  • encrypt—use HTTPS/SSL to encrypt data exchanged between the client and the server. This is especially critical for sites where user information and passwords are exchanged, or where confidential information such as account numbers or social security numbers are involved.
  • set Secure Cookies—to ensure SSL/HTTPS is in use, set your cookies as “Secure,” which limits the use of your application’s cookies to only secure web pages.
  • secure content—define a content security policy in your configuration file that sets the sources acceptable to JavaScript for codes, styles, fonts, etc. This restricts what sources of data will be accepted, rejecting any others.
  • set API access keys—assign individual tokens for each end-user. If these tokens don’t match up, access can be denied or revoked.

Being aware of these potential JavaScript security problems is an essential first step toward avoiding vulnerability in application development. Test your code with open source vulnerability scanner now.

Alyssa Miller Headshot
May 3, 2020
| By Alyssa Miller