The Internet was all about gray backgrounds and dull text boxes in the ’90s. But JavaScript changed all of that, allowing us to enjoy dynamic text, interactive websites, and clickable elements without sacrificing performance. JavaScript is one of the most commonly used programming languages today.
However, attackers are exploiting vulnerabilities in JavaScript applications with malicious scripts and session hijacking attacks to create a wide range of manipulations — such as session redirects, sensitive data harvesting (compliance breaches), and information tampering. Many ransomware variants exploit loopholes in JavaScript code, such as Magniber, Vjw0rm, and GootLoader. The MageCart group compromised British Airways, using just 22 lines of code to manipulate the Modernizr library.
So how do you make JavaScript more secure? There are dozens of ways adversaries exploit JS vulnerabilities, including difficult-to-counter attacks like cross-site scripting (XSS), session hijacking, OS command injection, regular expression (Regex) exploits, and spread operator injection. Well-established security habits can thwart some of these attacks. Let’s take a closer look at some attack techniques and the best cybersecurity practices to mitigate them.
Common Attacks and How to Defend Against Them
SQL injections (SQLi). SQL injection attacks target vulnerabilities such as encoding procedures and improper validation to execute malicious database commands.
To minimize the risks: Validate all inputs. Move away from using explicit SQL queries in code in favor of using object-relational mapping (ORMs). There are many great options, but I like TYPEORM.
Cross-site scripting (XSS). Attackers exploit vulnerabilities such as lack of validation or encoding in the web applications to insert malicious code. The contaminated application sends the code to the user as a browser-side script, which then gives attackers access to session tokens, cookies, passwords, and other kinds of personal information. There are different types of XSS attacks in use today — Reflected (Non-Persistent) XSS, Stored XSS, and DOM Based XSS being the most common variations.
To minimize the risks: Do not just trust content passed from users and run it; filter it upon arrival. Make sure that the content your server returns applies the matching content-type headers to ensure that browsers interpret the responses in the way you intend. Apply a content security policy whenever and wherever you can to control which content runs on your website and which origins you trust with this content.
Cross-site request forgery (CSRF). CSRF attacks are extremely common today. These exploits trick end users into performing and executing malicious actions while they are using Web applications. This happens after they have already been authenticated and usage has started. The main technique used here is social engineering, usually malicious emails or SMS messages with normal-looking links. Once the link is clicked, the payload is executed.
To minimize the risks: Use frameworks that come with built-in CSRF protection. You can also implement CSRF tokens to all requests that cause actions (state changing) and validate them on your backend.
Path traversal attacks. Also known as directory traversal attacks, path traversal attacks are used to gain unauthorized access to directories, configuration files, and sensitive passwords that have been stored (rather carelessly) outside the web root folder.
To minimize the risks: Avoid storing sensitive files outside your web root folder. Work without user input when using file system calls. Also, make sure that the user can’t supply all parts of the path by surrounding user input with your own path code. Lastly, implement strong code access policies (with chrooted jails) to restrict where the files can be obtained or saved to.
Server-side request forgery (SSRF). SSRF attacks exploit server-side vulnerabilities to perform a wide range of unauthorized activities — accessing sensitive resources (AWS metadata), connecting to internal services, manipulating data, and even modifying URLs to access data from secure vendors or channel customer information to remote servers. Besides using HTTP protocols, SSRF attacks can also use FTP, SMTP, and SMB.
To minimize the risks: Validate data and contexts. Look for V4 and V6 addresses. Cross-check provided IP addresses with the trusted vendor IP addresses. Don’t save data on servers — go with S3 buckets and blobs instead. Build a case-sensitive whitelist of trusted and identified domains. And never accept complete URLs from users — they are tough to validate.
Sensitive cookie exposure. There are many variations of sensitive data exposure vulnerabilities, but there’s a common theme in all of them: the exposure of information that should have been encrypted. The hackers also like to exploit weak cryptographic keys (for example, the MD5 password hashing algorithm that’s no longer considered secure) with brute force attacks that are powered by powerful ASICs and GPUs.
To minimize the risks: Classify all stored, processed, and transmitted data as per your regulatory requirements and apply controls accordingly. Discard unrequired sensitive data. Encrypt all data at rest and data in transit with TLS protocol, along with PFS ciphers and other secure parameters. Use HSTS. Disable all caching for responses that contain sensitive information.
In Summary: Best Practices
JavaScript is a true blessing thanks to its versatility and flexibility. It helps businesses create powerful user experiences and achieve enhanced functionality. But it also presents security requirements you need to consider. Only a proactive approach can help you steer clear of trouble — downtime, remediation costs, brand damage, lost business — and stay compliant with privacy regulations.
Here are some best practices you should have in place:
- Stay away from the eval() command in your code because it simply can execute a passed argument just like any regular JS expression.
- Prioritize encryption protocols, and also set all of your cookies as “secure” to limit their use and prevent hackers from exploiting them.
- Make a habit of setting API access keys. Once you start assigning individual tokens for end users, illegal access can automatically be denied.
- innerHTML is a very powerful DOM manipulation method, which doesn’t limit or escape the values passed to them. Use innerText instead.
It’s also a good idea to code securely and have a source code analysis (SCA) solution on board to detect vulnerabilities as early as possible. Traffic should also go through a proven and tested web application firewall (WAF). While neither of the two are silver bullets when it comes to JavaScript security — cyber immunity in general is a myth — you are always safer with multiple shield layers.