Linux 软件免费装
Banner图

Dragon Checkout Guard - PCI DSS Compliance & Card Skimming Detection for WooCommerce

开发者 dragoncoreltd
更新时间 2026年9月25日 18:55
PHP版本: 8.0 及以上
WordPress版本: 7.1
版权: GPLv2 or later
版权网址: 版权信息

标签

woocommerce payment page checkout security card skimming pci dss

下载

1.0.5 1.0.6 1.0.4 1.0.7 1.0.8

详情介绍:

Nearly every WooCommerce store embeds its gateway's card fields in an iframe: Stripe, WooPayments, PayPal, Braintree or Adyen. Since 31 March 2025, SAQ A carries an eligibility criterion that such a merchant has confirmed its site is not susceptible to attacks from scripts, and PCI SSC FAQ 1588 (February 2025) sets out the two ways to confirm it: apply techniques such as those in requirements 6.4.3 and 11.6.1 to your own page, or hold written confirmation from the PCI DSS validated provider that its embedded form includes script attack protections when implemented to the provider's instructions. That second route is not available from every provider, which leaves the first: an inventory of the scripts on the page around the iframe, a justification for each one, and a check that they have not changed. The iframe is the provider's. The page it sits in is yours, and a script injected into that page is what e-skimming (the Magecart style of attack) uses to read a shopper's details before the iframe ever sees them. Dragon Checkout Guard is the record of what runs on that page. It records, on your own WooCommerce checkout, order-pay, add-payment-method and (optionally) cart pages: It runs on your own server with no account, no JavaScript tag to a third party and no pageview cap. What it does What it is not Dragon Checkout Guard is not a Qualified Security Assessor, not a certification service, and not a substitute for your own PCI DSS assessment. It never claims a site "is compliant" or "is certified", and it does not determine which SAQ you complete: it produces evidence supporting the assessment you or your assessor make. Your acquirer or QSA settles your SAQ eligibility. It also cannot see inside your gateway's iframe. It is not meant to: that document is served by the provider from its own origin and is covered by the provider's own PCI DSS validation. The page around it is the merchant's, and that is what this plugin inventories.

安装:

  1. Upload the plugin files to /wp-content/plugins/dragon-checkout-guard, or install directly through the WordPress plugins screen.
  2. Activate the plugin through the 'Plugins' screen in WordPress.
  3. Visit Tools > Checkout Guard, open the Pages tab and confirm which pages are in scope, then use Open & capture or Scan now to record your first inventory.
  4. Review each script on the Inventory tab and authorise the ones that belong on your payment pages.
  5. Open the Assessment guide tab and answer the three questions, so the printable report carries the context your assessor needs.

屏幕截图:

  • The printable payment page script integrity record: assessment context, the authorised scripts and the ones still awaiting review, and the 11.6.1 check record, ready to hand to an assessor.
  • Response header baselines per payment page, so a change to Content-Security-Policy or framing controls is flagged instead of going unnoticed.
  • The assessment guide: answer three plain questions and it shows which PCI SSC FAQ 1588 route your answers point to and the records that route asks for.

升级注意事项:

1.0.8 Scans now read Checkout on a stock WooCommerce store using a one-product cart held in memory only. The first such scan may flag server-added headers: review and accept them. Add Payment Method still needs a signed-in customer, which is not an error. 1.0.7 Security hardening: the script inventory now matches what browsers actually load. 1.0.6 Translation-ready throughout. 1.0.5 Listing title and tags for WordPress.org, plus an optional review request on the plugin's own screen. 1.0.4 WordPress core scripts are now recognised on installs with a non-default wp-includes or wp-admin location. 1.0.3 Scripts whose type attribute carries a charset parameter are now inventoried: run a scan after updating. If you use a custom payment-page path with accented or percent-encoded characters, enter it again on the Settings tab. 1.0.0 Initial release of Dragon Checkout Guard.

常见问题:

Does this make my site PCI DSS compliant?

No. Dragon Checkout Guard produces evidence supporting your own PCI DSS 4.0.1 requirement 6.4.3 / 11.6.1 assessment. It is not a certification and does not, on its own, make a site compliant: your assessor still makes that determination.

Does it cover payment fields inside my gateway's iframe?

It covers the page the iframe sits in, which is the page that matters to you. The iframe document belongs to your provider and is covered by the provider's own PCI DSS validation. Your own page is what an injected script gets access to, and since 31 March 2025 an iframe merchant keeps SAQ A eligibility by confirming that page is not susceptible to attacks from scripts. PCI SSC FAQ 1588 accepts two confirmations: techniques such as those in 6.4.3 and 11.6.1 applied by you to your own page, or written confirmation from your PCI DSS validated provider that its embedded form includes script attack protections when implemented to its instructions. Providers rarely issue that written confirmation, so most merchants take the first route, and this plugin's inventory, authorisation record and weekly check is that route's evidence. If your payment page's own scripts can touch card data, you are on SAQ A-EP or SAQ D and 6.4.3 and 11.6.1 apply in full: the same records are what those requirements ask for. If your customer is redirected to the provider's own page to pay, the criterion does not apply to you, though assessors still commonly expect the page that starts the payment to be monitored. Confirm your SAQ eligibility with your acquirer or QSA: this plugin does not determine it for you. The Assessment guide tab walks the same three questions and shows which route your answers point at.

What does an assessor want to see?

Two documents and their history. The inventory CSV has one row per script with: script, type, party, pages, source, provider, owner, business purpose, justification, status, changed since authorised, authorised by, authorised at, integrity method, current hash, last checked, review due, first seen, last seen and, where a hash could not be taken, why not. The 11.6.1 check record CSV has one row per check that ran: checked at, trigger, pages checked, scripts checked, new scripts, changes detected, outstanding changes, headers outstanding, the outcome (no change; changes recorded for scripts, for security headers, or for both; or incomplete when a page could not be read), pages read, the pages not read and why, and script hashes verified. A response header this check found added, removed or changed makes the outcome a change, not "no change". "Print evidence report" renders both, with your assessment guide answers and the header baselines, as a printable "Payment page script integrity record". The same data is available from WP-CLI: wp dragon-checkout-guard export --type=inventory|evidence --format=csv|json.

How do I compare this to a server-side scanner?

Other WordPress plugins inventory the scripts your site's own code enqueues, from the server. Dragon Checkout Guard does that too, and then goes further: it can observe what actually ran in a real shopper's browser (which is where a tag manager's injected script first appears), it baselines and diffs the payment pages' response headers, it records an authorisation taxonomy per script (owner, purpose, justification, integrity method) rather than a bare list, it exports assessor-ready records, and it is fully driveable from WP-CLI.

Are there limits on the free version?

Nothing in this plugin is locked, limited or greyed out, and there is no limit on how many scripts or pageviews it records. An optional paid add-on, Dragon Checkout Guard Pro, adds an evidence ledger, alerts and a review queue; this plugin is complete without it. The plugin does apply operational limits so it stays cheap on a live store: see the next answer.

What are the limits?

  • Passive capture interval. A real shopper's pageview is sampled at most once per page per interval (a setting, in minutes, default 10), and that sampling reads the script registry rather than buffering the page. A pageview that shows the admin bar is not sampled. Scans and Open & capture always run, and those do buffer the response; an Open & capture leaves the admin bar's own scripts out, since no shopper is sent them.
  • Response capture cap. A buffered response (a scan or an Open & capture, never a passive pageview) is copied up to 5 MB (Server_Capture::MAX_BUFFER_BYTES); a larger page is passed through untouched and that capture is recorded as failed rather than partial.
  • Remote hashing. Only https script URLs are fetched. At most 200 remote fetches per UTC day. After 3 failures a host is backed off for 1 hour. A response over 2 MB is not hashed. Every script that could not be hashed says why on its row and in the export (host did not resolve, host resolves to a private address, host temporarily backed off, daily budget exhausted, fetch failed, response too large, local file not found, unsupported file type).
  • Stale scripts. A script not seen on any page for 30 days stops being refetched and shows "Not seen recently".
  • Browser collector. 30 reports per minute per address (IPv6 grouped by /64), 300 rows and 64 KB per report. 500 new observations in an hour, or 5000 unconfirmed in total, pause the collector for an hour and raise an admin notice; you can bulk dismiss observations from the Inventory tab or with wp dragon-checkout-guard dismiss. If the table reaches 4000 rows in total, the daily maintenance deletes the most recent unconfirmed observations - up to the number needed to bring the table down to 2500 - and records how many it took, so a flood cannot keep the collector shut off for 30 days. Confirmed observations are never deleted, so a table held up by confirmed rows is left as it is; a real script is reported again by the next shopper's browser.
  • Retention. Unconfirmed browser observations are pruned after 30 days. Event retention is a setting between 30 and 3650 days (default 365) and prunes only the low-value kinds: discovered, scan run, scan failed, collector tripped and settings changed. Everything else, including the evidence, authorised, revoked, changed, confirmed, headers changed, baseline accepted and browser observations cleared events, is kept regardless of the setting, because that is the record.
  • Exports. Exports carry at most 5000 rows and say so when they stop short.
  • One scan at a time. A lock stops the weekly cron, Scan now and WP-CLI overlapping. If the plugin's tables could not be created on activation, an admin notice says so and the install is retried automatically.

Which providers does it recognise?

Stripe, Stripe Radar, PayPal, Braintree, Adyen, Klarna, Mollie, Square, Google Pay, Apple Pay and WooPayments are recognised as payment or fraud scripts, and WooCommerce's own front-end scripts are recognised as WordPress store code, each with a suggested justification you can apply with one click. Google Tag Manager, Google Analytics, Meta Pixel, Hotjar, Intercom, Zendesk, LiveChat and ThreatMetrix are recognised too, and carry a reviewer note: a tag manager can pull further scripts onto a payment page, a chat widget is third-party code on a page you are attesting for, and session recording on a payment page records keystrokes unless it is masked or excluded. Anything unrecognised is listed plainly for you to justify or remove. A script is recognised by the host it is served from, by the plugin folder directly under your site's plugins directory that it is served from, or by the handle WordPress itself registered it under, as recorded by the plugin's server-side capture. A handle that only appears in the page's markup (an element id such as stripe-js-extra, or an importmap name) or in a shopper's browser is never used, since anything injected into the page could claim one.

How does a scan read Checkout when WooCommerce redirects an empty cart?

A scan's request is logged out and has no cart, and WooCommerce sends an empty-cart checkout to the cart. So the scan's own request, and only that request, gets a cart holding one product: the lowest-id published, purchasable, in-stock simple product priced above zero among the first 100 simple products, or the one you pick with the dragoncheckoutguard_scan_cart_product filter (return 0 to turn this off). The cart exists only in that request's memory. No WooCommerce session row, cookie, persistent cart, order or stock reservation is created, and no add-to-cart event fires; cart-total and checkout-page hooks still run, so a tool that records checkout views on the server may count one weekly scan visit. It is armed only by the scan's own single-use token (random, bound to the Checkout page, valid for 60 seconds and spent on first use), so an ordinary visitor can never trigger it. Checkout then renders, with its payment gateway scripts, the way it does for a shopper with an item in the cart, and the scan records it as read. Without a suitable product the scan is redirected as before, and the Pages tab says why. Once a scan reads Checkout, its response headers come from the scan's own request, which includes headers your web server or CDN adds. If Checkout's header baseline so far came only from shoppers' pageviews, the first such scan can flag those headers as changed: review them on the Headers tab and accept the baseline. Add Payment Method still needs a signed-in customer, so a scan records it as not read (it needs a signed-in customer). That is not an error; use Open & capture while logged in to record its scripts. Order Pay needs a real order and is skipped.

Will a scan show up in my analytics or abandoned-cart tool?

It can. To read Checkout, the weekly scan renders it with one product in a cart that exists only in that request's memory. No session, cookie, persistent cart or order is created and no add-to-cart event fires, but WooCommerce's cart-total and checkout-page hooks still run. A server-side analytics, conversion or abandoned-cart tool that records checkout views from those hooks may therefore count one visit per scan, with the DragonCheckoutGuard/ user agent. Browser analytics do not see it, since the scan runs no JavaScript. Filter that user agent out in the tool, or return 0 from the dragoncheckoutguard_scan_cart_product filter to scan Checkout without a cart (it is then recorded as redirected to the cart, not read).

Does a page cache affect this?

Two ways. First, the collector token embedded in the page: rotating it invalidates the old one immediately, but a full-page cache keeps serving pages with the old token baked in until it is cleared, so any real shopper served from cache reports with a rejected token in the meantime. Clear your page cache right after rotating. Second, a cached checkout response can mean the header baseline you are comparing against is the cache's own headers rather than your origin server's; scan with the cache bypassed, or exclude payment URLs from full-page caching, for headers evidence to be meaningful.

What does the browser collector send, and where does it go?

It sends the list of scripts (URLs and content hashes, plus which page they ran on) that were actually observed running in a shopper's browser, to a REST endpoint on your own site: that report never leaves your server. It never sends personal data: no name, email, IP address, cookie or session identifier is included in a report, and none is stored against it. The endpoint's rate limit uses a salted hash of the address, kept in a transient for two minutes; on sites without a persistent object cache that transient lives in the options table for that time. Inline script previews are stored with sensitive values redacted. (The plugin does make its own outbound requests for a different reason: see the next question.)

Does this plugin contact any external services?

It has no service of its own: nothing is ever sent to Dragon Core, and there is no account and no telemetry. The one outbound request it makes is downloading a script your payment page already loads from another host, so it can hash the contents and notice a change. A script on your own site is read from disk instead. The request is a plain HTTPS GET of that public URL, with the connection pinned to the validated address where the site's HTTP transport supports it (curl), and it carries nothing about your site, its configuration or its visitors. The External services section above lists exactly what is sent, when and where.

Does it work with Dragon Activity Log?

Yes. If Dragon Activity Log is active, Dragon Checkout Guard records script.authorised, script.revoked, script.changed, headers.changed and collector.tripped to it, with script.changed and collector.tripped raised as the higher severity. Its own event log works with or without it.

Can I remove all of this plugin's data when I uninstall it?

Yes, but you have to opt in first. By default, uninstalling keeps your script inventory, authorisations and headers baseline so a reinstall picks up where you left off. Tick Delete this plugin's tables, options and evidence when it is uninstalled on the Settings tab (or set the dragoncheckoutguard_delete_data_on_uninstall option) before uninstalling if you want everything removed instead.

更新日志:

1.0.8 1.0.7 1.0.6 1.0.5 1.0.4 1.0.3 1.0.2 1.0.1 1.0.0