Charity Hacked: Web Skimmer Infected Caritas Spain Websites for Over a Year
April 23rd, 2025 | By Pedro Fortuna | 20 min read
with David Alves and Pedro Marrucho
This research documents Jscrambler’s investigation into a stealthy web skimming campaign that infiltrated multiple Caritas Spain websites of Caritas Internationalis, a confederation of over 160 Catholic relief, development, and social service organizations operating in more than 200 countries and territories.
All targeted Caritas Spain websites were running WooCommerce, the popular e-commerce plugin for WordPress. The attack chain consisted of two distinct stages, carefully designed to remain undetected while intercepting sensitive payment data.
This campaign reinforces a broader trend that has been observed: web skimming infections are increasingly driven by modular kits. These toolkits enable attackers to mix and match various delivery mechanisms, support multiple communication channels within their infrastructure, and deploy flexible combinations of loader and skimmer scripts. Jscrambler was able to confirm that the threat actors' automated validation and use of the stolen cards occurs soon after they are captured.
What makes this case especially concerning is the nature of the victim: Caritas is a non-profit dedicated to helping vulnerable communities. Still, attackers were happy to keep their skimming operation going on seventeen Caritas España sites for over a year until it was shut down recently.
How the attack works
The skimming campaign, like many, was executed in two stages. Stage one served as the loader, laying the groundwork for the attack. Stage two held the skimmer logic itself, injected a fake payment form, and exfiltrated sensitive data.
Stage 1: Entry point and loader
The initial infection vector remains unknown. It could have been an exploited vulnerability, a misconfigured server, a compromised plugin, or credentials theft. In this type of infection, threat actors usually ensure they can retain access even if the initial vulnerability or misconfiguration is patched or fixed in the meantime.
It was observed that the Stage 1 loader was injected as a one-liner at the bottom of the minified WooCommerce JavaScript: cart-fragments.min.js, which runs on the homepage.
https://www.caritas.es/main-files/plugins/woocommerce/assets/js/frontend/cart-fragments.min.js?ver=6.1.2
Here’s what that one-liner looks like:
Listing 1 - Sample stage 1 loader
This one-liner (lightly obfuscated) executes the following logic:
Clears a key (XsuHCYmfbgVSRFVx7SHRnU7DfapjFpaf) from localStorage (this entry is associated with a potential web socket connection);
Checks for another key (QIQWJJnh1Ckclw0jFr5KPME2M3kYHTyq) to avoid multiple skimming attacks on the same device;
Dynamically constructs a URL using String.fromCharCode — in this case, https://categorywishlist.com;
Sends a POST request to that endpoint;
If the response is successful, the loader:
gets a JSON response that, among other things, includes a property called response.data containing the following subproperties:
“script”: the URL from where the stage2 script must be loaded,
“handler”: the URL to where skimmed data will be exfiltrated by the Fetch method,
“Socket”: an alternative exfil channel using Web Sockets
Listing 2 - Sample JSON returned by the categorywishlist.com endpoint
The arrays above are strings using the same obfuscation technique as before. Using String.fromCharCode, you get:
Listing 3 - JSON after decoding string elements
Then “socket” and “handler” are saved, respectively, into Local Storage items “XsuHCYmfbgVSRFVx7SHRnU7DfapjFpaf” and “XsuHCYmfbgVSRFVx7SHRnU7DfapjFpaf_handler”
6. Loads a stage 2 script from https://newsasssets\.com/caritas\.js by appending it to the head section of the DOM.
Any errors are caught by the script so as to avoid triggering errors that could lead to an earlier discovery of the attack.
Stage 2: Fake payment form and exfiltration
Image 1 - Donor form
Once loaded, the second-stage script monitors for the selection of the Tarjeta (payment card) payment option. When detected, it injects a fake Continuar (Proceed) submit button and hides the real one.
Image 2 - Payment Card option selected on the donor's form
Image 3 - Fake button inject function (deobfuscated for improved readability)
Once the user submits the initial form, it overlays it with a fake payment form on the same domain (caritas.es) that visually resembles the legitimate payment gateway (Redsys on behalf of Santander). The skimmed data — cardholder name, number, expiry, and CVV — is collected and exfiltrated via a covert Image.src request to https://hotjarws\.com/b\.php, base64 encoded.
Collected data:
Cardholder data:
User Agent
Email
First Name
Last Name
Address
City And Postcode
Cardholder name
Phone
DNI
Payment card number
Expiry date
CVV
Collected from:
website
Image 3 - Fake payment form running at Caritas.es
Image 4 - Exfiltrated data
After the user submits the fake payment form, the overlay is removed, and a loading spinner is shown for a few seconds. Then, the donor form is shown again. At this point, provided that the user does not deselect the target (card), if the user clicks Continuar (submit), they are redirected to the legitimate PSP site to proceed with the donation.
Image 5 - Legitimate payment form on sis.redsys.es
While the visual representation is convincing, the differences become obvious after the user is taken to the second payment form. By comparing Images 3 and 5, they are easily spotted. The question is whether these differences are sufficient to prompt users to report them to Caritas, and, if so, how those reports are being processed.
Infected websites
The team checked all Caritas related websites and we found the same skimming campaign affecting the following 17 websites:
caritas.es
caritasespanola.org
caritasdtr.org
caritasoa.org
caritastortosa.org
caritas-sc.org
caritasmalaga.es
caritasmallorca.org
caritasmeba.es
caritasplasencia.org
caritasvalencia.org
caritas-zaragoza.org
caritasbi.org
caritasbisbatvic.cat
caritasjaen.es
caritasregiondemurcia.org
diocesanaterrassa.caritas.es
Most websites were hosted under the same IP address, indicating centralized management or a shared infrastructure. A few exceptions exist (3), but the majority were under the same IP, and they are likely being managed using a common backend administration panel.
Image 6 - Infected websites infrastructure graph
Research timelines
This campaign was first detected on March 16th, 2025. Soon enough, all seventeen infected websites from Caritas in Spain were found, along with all domains and IP addresses involved. Then, between April 1st and 3rd, 2025, the stage 1 categorywishlist\.com and the C2 domain newassets\.com went offline, but the websites were still infected with Stage 1. On April 3rd at 1 am, the C2 domain came back with a new IP:
At this point, Jscrambler started reaching out to victims. The team reached out to Caritas on April 4th. All Caritas-infected websites were down for maintenance shortly after.
Image 7 - Websites under maintenance
When they returned online, few things had changed. All websites were still infected, but the point of infection was now on a different WooCommerce script:
The Jscrambler Research Team couldn’t confirm whether the previous script was cleaned by Caritas or if the threat actors had simply changed the infection point elsewhere, perhaps as an evasion tactic. Evidence suggests that the threat actors have persistent access to the WooCommerce installation.
Besides that change, the skimmer stack remained the same, except that a skimmer-related domain changed. Instead of using categorywishlist\.com for the Stage 1 JSON request, it was now using assetssafepay\.com. All other skimmer-related domains remained unchanged.
Jscrambler reached out again to Caritas, and by April 11th, 2025, we confirmed the infection had been removed.
Other targets and skimming insights
The same campaign targeted several websites beyond Caritas. The Jscrambler Research Team discovered that this particular threat actor was leveraging an unusually high number of domains, totaling 61, most of which were hosted under the same IP address that had recently been assigned to their C2 server (see Image 7).
When an attacker uses such a large volume of domains, attempting to take them down individually is often ineffective. Taking down the IP address — for example, by reporting it to the hosting provider — is typically a more impactful countermeasure, especially when many sites are hosted on the same infrastructure.
Image 8 - Domains used by the Threat Actor
Across other victim websites, we observed variations of the same attack. These differences appeared in both the loader scripts (Stage 1) and the main skimmer logic (Stage 2):
Stage 1 loaders: varied in location and method. Some were injected into different plugins or scripts, including those loaded via a legitimate Google Tag Manager (GTM) or through scripts pretending to be GTM. The loader code itself also showed multiple variations.
Stage 2 scripts: clearly generated by a tool, all very similar, usually obfuscated. In some cases, we saw a comment header typically associated with Google Closure Compiler: Copyright The Closure Library Authors. SPDX-License-Identifier: Apache-2.0. While the team cannot confirm whether Closure Compiler was actually used, it is plausible that the attacker inserted this comment deliberately to make the script appear more legitimate. If Closure Compiler was used at some point, its traces may have been overwritten by subsequent layers of obfuscation. It's worth noting that Closure Compiler is intended for minification, not obfuscation; however, the distinction may be lost on defenders performing a quick analysis.
Interestingly, some victims appeared aware that something was wrong, but lacked the means or knowledge to properly address it. On one merchant’s site, there was an attempt to block the skimmer by injecting a script designed to prevent the stage 2 payload from loading from paysafeprocess\.com.
Image 9 - A merchant’s attempt to fix the problem
How fast is stolen data used?
The Jscrambler Research Team wanted to understand how quickly stolen payment data from this campaign was being used. To do so, a canary payment card was deployed from Thinkst — a specially generated card number intended for use as a decoy and not for legitimate transactions. If this card is used or even tested for authorization, it triggers an alert, confirming that it has been compromised. Think of it as a payment card honeypot.
Using a canary card service, a card was created and submitted through the fake form on caritas\.es. Within just 10 minutes, an alert was received.
Image 10 - Canary Payment Card triggered alert
Given how quickly the card was tested, it's likely that the threat actor’s infrastructure is automated to validate stolen cards soon after they are captured.
Highly persistent infection
As stated above, the Jscrambler Research Team first detected this infection in mid-March 2025. However, by examining historical snapshots from Archive.org and other web-crawling services, the initial infection was traced back to February 22nd, 2024.
Image 11 - First sign of infection on February 22nd, 2024
Over time, it was observed that different scripts were being infected, multiple skimming techniques were deployed, and there were periods of dormancy. These signs strongly suggest that the threat actors had persistent access to the WooCommerce environments, allowing them to reintroduce or modify the skimming code at will, shift infection points, and rotate infrastructure domains as needed.
As of April 11th, 2025, Jscrambler confirmed that the skimmer was no longer active. However, from our external vantage point, we cannot determine whether the attacker still retains any level of access to the affected systems.
How to protect against web skimming
To mitigate the risk of web skimming, organizations that accept online payments should consider implementing robust security solutions. Merchants accepting payment card payments are already contractually obligated to comply with security standards such as PCI DSS.
Specifically, the following requirements apply:
Requirement 6.4.3: Merchants must ensure that all payment page scripts are authorized and have a method to assure their integrity. This means cataloging which scripts are expected to run on the payment page, validating their sources, and implementing integrity checks.
Requirement 11.6.1: Merchants must implement a change- and tamper-detection mechanism to alert on unauthorized modifications to HTTP headers and the contents of payment pages as received by the consumer browser. This requires the ability to detect if a skimmer or rogue script is injected post-deployment.
Implementing script behavior-based monitoring solutions, such as Jscrambler Webpage Integrity, can detect unauthorized script injections and enforce PCI DSS requirements 6.4.3 and 11.6.1.
Given that small merchants often lack the expertise or resources to fully implement the stringent requirements of PCI DSS, these automated solutions provide an essential layer of protection. Equally important is having an incident response plan in place that includes how to communicate with users and restore trust after an incident.
Web skimming prevention requires a combination of technical controls, process rigor, and continuous visibility into what is executing on your users' browsers during checkout.
Conclusion
Losing payment card numbers to threat actors is always a serious matter, regardless of the context. When it happens in a typical online shopping scenario, the impact is significant. However, when someone visits a website solely to make a donation to a charitable cause and their cardholder data is stolen in the process, it feels especially disheartening.
This incident serves as a powerful reminder that web skimming is a threat that transcends organization size, mission, or industry. Threat actors don’t discriminate — if a website processes cardholder data, it’s a viable target.
Skimming operations are increasingly relying on automation. From searching and infecting victims, to validating and using the stolen data. There is a market for skimming kits, which invites new threat actors to set up their skimming operations. This attack also demonstrates that these attacks can persist for extended periods, making web skimming a highly profitable activity for threat actors.
If your organization processes online payments, ensuring the integrity of what users see in their browsers is critical. To learn how Webpage Integrity can help you detect and stop web skimming attacks before they cause harm, get in touch with us — we're here to help.
Indicators of Compromise (IOCs):
GTM IDs
GTM |
GTM-KJJ3BFKC |
Indicators of Compromise (IOCs):
Malicious Domains
C2 | IP | ASN | ASN-NAME | ASN-COUNTRY |
paysafeprocess[.]com | 86[.]54[.]42[.]111 | 42624 | SWISSNETWORK02, SC | Seychelles |
analysiscache[.]com | 86[.]54[.]42[.]111 | 42624 | SWISSNETWORK02, SC | Seychelles |
analysisdoubleclick[.]com | 86[.]54[.]42[.]111 | 42624 | SWISSNETWORK02, SC | Seychelles |
assets-token[.]com | 86[.]54[.]42[.]111 | 42624 | SWISSNETWORK02, SC | Seychelles |
assetshotjar[.]com | 86[.]54[.]42[.]111 | 42624 | SWISSNETWORK02, SC | Seychelles |
assetssafepay[.]com | 86[.]54[.]42[.]111 | 42624 | SWISSNETWORK02, SC | Seychelles |
bundlereferrer[.]com | 86[.]54[.]42[.]111 | 42624 | SWISSNETWORK02, SC | Seychelles |
analysistoken[.]com | 86[.]54[.]42[.]111 | 42624 | SWISSNETWORK02, SC | Seychelles |
notificationfeedback[.]com | 86[.]54[.]42[.]111 | 42624 | SWISSNETWORK02, SC | Seychelles |
cachereferrer[.]com | 86[.]54[.]42[.]111 | 42624 | SWISSNETWORK02, SC | Seychelles |
campaigntransaction[.]com | 86[.]54[.]42[.]111 | 42624 | SWISSNETWORK02, SC | Seychelles |
categorywishlist[.]com | 86[.]54[.]42[.]111 | 42624 | SWISSNETWORK02, SC | Seychelles |
cdn-secure[.]com | 86[.]54[.]42[.]111 | 42624 | SWISSNETWORK02, SC | Seychelles |
cdnmozilla[.]com | 86[.]54[.]42[.]111 | 42624 | SWISSNETWORK02, SC | Seychelles |
cdnnewassets[.]com | 86[.]54[.]42[.]111 | 42624 | SWISSNETWORK02, SC | Seychelles |
explorerstripe[.]com | 86[.]54[.]42[.]111 | 42624 | SWISSNETWORK02, SC | Seychelles |
gravatargo[.]com | 86[.]54[.]42[.]111 | 42624 | SWISSNETWORK02, SC | Seychelles |
platformwebsite[.]com | 86[.]54[.]42[.]111 | 42624 | SWISSNETWORK02, SC | Seychelles |
heure-planification[.]com | 185[.]208[.]158[.]121 | 42624 | SWISSNETWORK02, SC | Seychelles |
hipaye[.]com | 86[.]54[.]42[.]111 | 42624 | SWISSNETWORK02, SC | Seychelles |
hotjarmultisafe[.]com | 86[.]54[.]42[.]111 | 42624 | SWISSNETWORK02, SC | Seychelles |
interfaceuser-friendly[.]com | 86[.]54[.]42[.]111 | 42624 | SWISSNETWORK02, SC | Seychelles |
locationchrome[.]com | 86[.]54[.]42[.]111 | 42624 | SWISSNETWORK02, SC | Seychelles |
ratingrecommendation[.]com | 86[.]54[.]42[.]111 | 42624 | SWISSNETWORK02, SC | Seychelles |
recommendationtrend[.]com | 86[.]54[.]42[.]111 | 42624 | SWISSNETWORK02, SC | Seychelles |
inventoryvoucher[.]com | 86[.]54[.]42[.]111 | 42624 | SWISSNETWORK02, SC | Seychelles |
timestampcdn[.]com | 86[.]54[.]42[.]111 | 42624 | SWISSNETWORK02, SC | Seychelles |
referrerlocation[.]com | 86[.]54[.]42[.]111 | 42624 | SWISSNETWORK02, SC | Seychelles |
refundpurchase[.]com | 86[.]54[.]42[.]111 | 42624 | SWISSNETWORK02, SC | Seychelles |
safepaymultisafe[.]com | 86[.]54[.]42[.]111 | 42624 | SWISSNETWORK02, SC | Seychelles |
securedata-ns[.]com | 86[.]54[.]42[.]111 | 42624 | SWISSNETWORK02, SC | Seychelles |
securi-analitycs[.]com | 86[.]54[.]42[.]111 | 42624 | SWISSNETWORK02, SC | Seychelles |
staticreview[.]com | 86[.]54[.]42[.]111 | 42624 | SWISSNETWORK02, SC | Seychelles |
stockbarcode[.]com | 86[.]54[.]42[.]111 | 42624 | SWISSNETWORK02, SC | Seychelles |
jguery-web[.]com | 86[.]54[.]42[.]111 | 42624 | SWISSNETWORK02, SC | Seychelles |
web-jguery[.]com | 86[.]54[.]42[.]111 | 42624 | SWISSNETWORK02, SC | Seychelles |
stripehotjar[.]com | 86[.]54[.]42[.]111 | 42624 | SWISSNETWORK02, SC | Seychelles |
tag-secure[.]com | 86[.]54[.]42[.]111 | 42624 | SWISSNETWORK02, SC | Seychelles |
user-friendlyexperience[.]com | 86[.]54[.]42[.]111 | 42624 | SWISSNETWORK02, SC | Seychelles |
webjguery[.]com | 86[.]54[.]42[.]111 | 42624 | SWISSNETWORK02, SC | Seychelles |
webjquery[.]com | 86[.]54[.]42[.]111 | 42624 | SWISSNETWORK02, SC | Seychelles |
wishlistnotification[.]com | 86[.]54[.]42[.]111 | 42624 | SWISSNETWORK02, SC | Seychelles |
ads-advertise[.]com | 86[.]54[.]42[.]111 | 42624 | SWISSNETWORK02, SC | Seychelles |
multisafebundle[.]com | 86[.]54[.]42[.]111 | 42624 | SWISSNETWORK02, SC | Seychelles |
paysafeprocess[.]com | 86[.]54[.]42[.]111 | 42624 | SWISSNETWORK02, SC | Seychelles |
analysis-ns[.]com | 86[.]54[.]42[.]111 | 42624 | SWISSNETWORK02, SC | Seychelles |
hotjarws[.]com | 86[.]54[.]42[.]111 | 42624 | SWISSNETWORK02, SC | Seychelles |
mozillastatus[.]com | 86[.]54[.]42[.]111 | 42624 | SWISSNETWORK02, SC | Seychelles |
firefoxcaptcha[.]com | 86[.]54[.]42[.]111 | 42624 | SWISSNETWORK02, SC | Seychelles |
experienceresponsive[.]com | 86[.]54[.]42[.]111 | 42624 | SWISSNETWORK02, SC | Seychelles |
newsassets[.]com | 86[.]54[.]42[.]111 | 42624 | SWISSNETWORK02, SC | Seychelles |
checkoutcache[.]com | 86[.]54[.]42[.]111 | 42624 | SWISSNETWORK02, SC | Seychelles |
cdnweb2analytics[.]com | 86[.]54[.]42[.]111 | 42624 | SWISSNETWORK02, SC | Seychelles |
cdnsafepay[.]com | 86[.]54[.]42[.]111 | 42624 | SWISSNETWORK02, SC | Seychelles |
bundle-referrer[.]com | 86[.]54[.]42[.]111 | 42624 | SWISSNETWORK02, SC | Seychelles |
cloudsolutio[.]com | 86[.]54[.]42[.]111 | 42624 | SWISSNETWORK02, SC | Seychelles |
cachecaptcha[.]com | 86[.]54[.]42[.]111 | 42624 | SWISSNETWORK02, SC | Seychelles |
assets-tokens[.]com | 86[.]54[.]42[.]111 | 42624 | SWISSNETWORK02, SC | Seychelles |
advertcheckout[.]com | 86[.]54[.]42[.]111 | 42624 | SWISSNETWORK02, SC | Seychelles |
token-analysis[.]com | 86[.]54[.]42[.]111 | 42624 | SWISSNETWORK02, SC | Seychelles |
approvalreceipt[.]com | - | - | - | - |
stripepayway[.]com | - | - | - | - |
Jscrambler
The leader in client-side Web security. With Jscrambler, JavaScript applications become self-defensive and capable of detecting and blocking client-side attacks like Magecart.
View All ArticlesMust read next
Stripe API Skimming Campaign: Additional Victims and Insights
A recently discovered web skimming campaign has introduced a novel technique that leverages a legacy Stripe API to validate stolen payment details before exfiltrating them.
April 2, 2025 | By Pedro Fortuna | 13 min read
Stealing Seconds: Web Skimmer Compromises Casio UK and Growing Number of Websites
Jscrambler just uncovered a new batch of web skimmer infections affecting multiple websites, including casio.co.uk. So far, 17 victim websites are confirmed, though this number will likely increase...
January 31, 2025 | By Pedro Fortuna | 10 min read
