kraftware/sw6-store-api-captcha

Enforce Shopware core captchas on Store API routes

Maintainers

Package info

github.com/runelaenen/sw6-store-api-captcha

Type:shopware-platform-plugin

pkg:composer/kraftware/sw6-store-api-captcha

Transparency log

Statistics

Installs: 2

Dependents: 0

Suggesters: 0

Stars: 0

Open Issues: 0

7.0.0 2026-07-15 08:06 UTC

This package is auto-updated.

Last update: 2026-07-15 08:07:41 UTC


README

Enforce Shopware's core captchas on Store API routes. Shopware only enforces captchas on Storefront routes out of the box; this plugin extends the same captcha framework to the Store API, which is useful for headless / composable frontends and API integrations.

No new captcha type is added. The plugin reuses the captchas registered under the shopware.storefront.captcha tag (Honeypot, Google reCAPTCHA v2/v3, and any third-party captcha such as Cloudflare Turnstile) and the captcha selection configured under Settings → Basic information.

How a route gets protected

A Store API route is protected when either:

  1. It declares the _captcha route attribute — parity with how Storefront routes opt in. Plugin authors add defaults={"_captcha"=true} (or the attribute equivalent) to their own Store API route. Example:

    #[Route(path: '/store-api/my-route', name: 'store-api.my-route', defaults: ['_captcha' => true], methods: ['POST'])]
  2. Its route name is listed in the plugin configuration — open the plugin config and add one Store API route name per line, e.g.:

    store-api.account.register
    store-api.contact.form
    

    Use mechanism 2 to protect existing core or third-party routes without changing their code.

Matching is by exact route name (the Symfony _route).

Behaviour

  • Runs only for requests in the store-api route scope; Storefront and Admin API behaviour is untouched.
  • On captcha failure the request is rejected with the core CaptchaException: HTTP 403, error code FRAMEWORK__INVALID_CAPTCHA_VALUE, as a Store API JSON error.
  • On success the request proceeds normally.
  • Honors per-sales-channel configuration for both the route list and the captcha selection.
  • Only POST requests are validated. The core captchas apply to form/POST submissions and return supports() === false for other methods. GET requests are never captcha-checked, so protect state-changing POST routes. Adding a GET-only (or GET-served) route to the list does not captcha-protect its GET traffic.

Client responsibility

This plugin only validates. The API client must obtain the captcha token and send the captcha parameter in the request body, e.g. _grecaptcha_v3 for Google reCAPTCHA v3. Captcha parameters sent in a JSON body are read correctly (Shopware decodes the JSON body into the request parameters before validation).

Notes and limitations

  • Storefront bundle required. The captcha implementations live in shopware/storefront, which is a hard dependency. A pure headless install without the Storefront bundle is not supported.
  • Token-based captchas recommended. Google reCAPTCHA v2/v3 (and other token-verified captchas) are stateless and work well over the Store API.
  • BasicCaptcha is skipped, not enforced. The image-based BasicCaptcha reports shouldBreak() === false because it expects an interactive image/session challenge that cannot be presented to a stateless API client. Rather than hard-block every request, the plugin skips any active captcha whose shouldBreak() is false. Do not rely on BasicCaptcha for Store API protection.
  • Honeypot is weak on a headless client. Honeypot treats an empty field as valid, which works against bots that blindly fill hidden form fields. A first-party API client simply never sends the field, so honeypot passes every request and provides little real protection over the Store API. Prefer a token-verified captcha.