{"uuid": "d5f30da0-5e64-43b2-83b9-7d3fbd9c60a2", "vulnerability_lookup_origin": "1a89b78e-f703-45f3-bb86-59eb712668bd", "author": "9f56dd64-161d-43a6-b9c3-555944290a09", "vulnerability": "CVE-2024-34102", "type": "seen", "source": "https://gist.github.com/o0mohd0o/3bacf588df9a3711c7dbd35d361fc686", "content": "# The code is clean, but checkout leaks card data to an unknown domain. Where can a skimmer live without touching PHP or templates, how do you find it, and what do you rotate?\n\n## Short answer\n\nMagento renders a lot of **database-stored HTML** on the storefront. Attackers who get admin access, or abuse a vulnerability, put the skimmer there because file-integrity tools and `git status` never look at it. The usual places are the design configuration fields (**HTML Head &gt; Scripts and Style Sheets** and **Footer &gt; Miscellaneous HTML**), CMS blocks and pages, and widget instances. Clean them, then close the entry point: patch, remove rogue admins and integrations, kill sessions and tokens, and **rotate the encryption key** if the attacker may have read `app/etc/env.php`.\n\n## Where it hides (no file changes needed)\n\n| Location | Table / path | Rendered |\n|---|---|---|\n| Design &gt; HTML Head &gt; Scripts and Style Sheets | `core_config_data` path `design/head/includes` | `` of every page, including checkout |\n| Design &gt; Footer &gt; Miscellaneous HTML | `core_config_data` path `design/footer/absolute_footer` | Before `` on every page |\n| CMS blocks / pages | `cms_block.content`, `cms_page.content` | Wherever placed, often in a footer block |\n| Widgets | `widget_instance.widget_parameters` | Layout positions, can target checkout |\n| Email templates | `email_template.template_text` | Phishing via transactional emails |\n\nAlso check generated files that are **not in git**, so `git status` can't see them: `pub/static/**` JS (regenerated on deploy, but writable at runtime), and anything executable under `pub/media`.\n\n## Diagnosis\n\n```sql\n-- Script tags or obfuscation in any config value, at any scope\nSELECT config_id, scope, scope_id, path, LEFT(value, 300) AS snippet\nFROM core_config_data\nWHERE value LIKE '% Other Settings &gt; Manage Encryption Key**). Patching alone doesn't invalidate a key that was already stolen.\n   - Reset all admin passwords, delete unknown admin users and integrations, and revoke OAuth tokens.\n   - Rotate the DB password, payment gateway API keys, and SMTP and third-party API keys stored in config.\n4. **Harden.**\n   - Enforce 2FA for the admin (`Magento_TwoFactorAuth`).\n   - Use a non-default admin URL and an IP allowlist.\n   - Restrict who can edit **Content &gt; Design &gt; Configuration** via ACL.\n   - Keep Content-Security-Policy in restrict mode on checkout (the default for payment pages since 2.4.7) with `report-uri` set, so a new external script on checkout is blocked and reported.\n5. **Notify.** Card data exposure has PCI DSS and legal reporting obligations. Involve the payment provider early.\n\n## Follow-up questions\n\n1. **CSP is enabled on checkout. How did the skimmer still exfiltrate data?**\n   Common reasons: CSP is in report-only mode, or the exfiltration domain is allowed by an over-broad whitelist (`*.example-cdn.com`, or a whole shared analytics domain). Attackers also exfiltrate through domains you already allow, such as analytics endpoints and WebSockets. Review `csp_whitelist.xml` across all modules, not just yours.\n\n2. **How do you detect the next injection in minutes instead of weeks?**\n   Monitor the database, not just files: alert on changes to `design/head/includes`, `design/footer/absolute_footer`, `cms_block`, and `admin_user` (DB triggers into an audit table, or a scheduled diff). Monitor rendered checkout HTML from outside (a synthetic check that hashes the scripts loaded on the payment step), and collect CSP violation reports.\n", "creation_timestamp": "2026-10-03T13:05:58.000000Z"}