Protecting applications from malicious scripts
In 2018, malicious client-side scripts are still posing a problem for large organizations. This year, British Airways revealed that they suffered a data breach in which 380,000 records were exfiltrated. Now, NewEgg has been hit with a similar data breach. This follows a string of attacks from a group known as Magecart, who were also responsible for publicized data breaches of Ticketmaster and Feedlify.
Any time malicious Javascript is loaded onto a critical page– for instance, a payments page– it has the potential to wreak havoc. The Magecart script, specifically, can exfiltrate data using the exact same method each time: when a form is submitted by a user, the information is skimmed and then sent to a server controlled by the attackers. Some internet experts have offered quick fixes to prevent malicious Javascript from exfiltrating data on payment pages, like putting the form in an iFrame or randomizing the form and input field names. While these controls may be useful for this particular morphology of attack, they do not provide a comprehensive defense for the many variations of attacks in the same category.
Put simply, the solution to preventing these kinds of attacks is to avoid giving client applications, such as web browsers, bad code to run in the first place. You can prevent this from happening by using a number of scenario-specific strategies, such as protecting against cross-site scripting attacks, protecting against compromised code libraries, and following best practices to prevent web servers from being compromised. The idea with these strategies is to shift left, and to ensure that security controls are applied to your software from the beginning stages of the software development lifecycle (SDLC).
Protecting Against Cross-Site Scripting (XSS) attacks
1. Escape untrusted data in HTML, HTML attributes, CSS, and JavaScript. Developers must neutralize any untrusted user inputs (that may cause unintended application behavior) before rendering any output content.
2. Use JavaScript Strict Mode. Strict mode improves the security of JavaScript code by mandating higher code quality (e.g. through explicit declaration of variables). It reduces the possibility of unintended manipulation of global variables, coding errors and coding mistakes.
3. Enforce policies through content security policy (CSP) headers. Use CSP headers to specify trusted sources for loading data and scripts. Using ‘connect-src’ and ‘action-form’ directives can drastically reduce the risk of data exfiltration and sending the data to an untrusted destination.
4. Apply best practices to avoid DOM-based Cross-Site Scripting. This is a special case that requires extra attention from developers to prevent DOM properties from being controlled via unsafe and malicious scripts.
5. Set ‘HttpOnly’ session cookie attribute. Reduce the impact of XSS by disallowing attackers to read and send the content of cookies to a malicious target.
Protecting against compromised code libraries
1. Avoid dynamically loading any code without proper security considerations. Dynamic loading of code increases code complexity and adds to the risks of code injection and code tampering, especially when the code files are on shared resources that are accessible to other applications or when they are transferred over an unsecured network. Always load the libraries (e.g. JavaScript libraries) from trusted domains and load them through a secure (HTTPS) channel.
2. Follow best practices for using third-party and commercial off-the-shelf components. Do not use components with known vulnerabilities. Be sure to acquire components from reputable and reliable sources, to check firmware signatures, or to verify signed file hashes (digital signatures) so that you can ensure that the hardware and software are not modified. Software Composition Analysis (SCA) tools may be employed to help manage and track components.
3. Verify that third party libraries use secure settings and the latest patches. The entire system can become vulnerable from a single component. Be diligent in tracking and patching all third-party components. Make sure to update and patch the libraries from the original trusted source and verify the signatures before running the updates.
4. If the web app has a payments page, remove all unnecessary functionality and debug information, including scripts, according to PCI DSS guidelines.
Protecting web servers from being compromised
Use multi-factor authentication for remote access to high-risk systems or for administrative access to services. This helps to prevent the write access that attackers may use to inject malicious scripts when code libraries are hosted on internal servers. Note that the malicious attacker can be an insider with unnecessary permissions.
Shifting security left
Addressing problems with faulty code starts with designing security into the code. That means software development processes that identify and fix vulnerabilities during design and coding should be established. This saves you from having to test and repair vulnerabilities later on. In agile development and DevOps environments, the concept of shift left has become important. Shifting left means taking care of security from the start of the SDLC and throughout the SDLC. It is building security in from the start, and it allows organizations to embed the appropriate security considerations into the requirements phase. This ultimately will help reduce the cost to maintain software and protect against data breaches.