Skip to content

Releases: SimonHayter/cloudflare-turnstile-rocket-loader-fix

v1.1.1 — Housekeeping

Choose a tag to compare

@SimonHayter SimonHayter released this 10 Sep 16:47

No functional change. The plugin behaves identically to 1.1.0.

Changed

  • The index.php directory stubs now carry a proper /** */ file docblock instead of a // Silence is golden. line comment. 1.1.0 kept WordPress core's verbatim two-line form and scoped Squiz.Commenting.FileComment away from those files in phpcs.xml.dist; satisfying the sniff is preferable to suppressing it, so the exclusion is gone and the ruleset is stock WordPress plus PHPCompatibilityWP with a single documented exclusion.

Install: download cloudflare-turnstile-rocket-loader-fix-1.1.1.zip below, then Plugins → Add New → Upload Plugin in WordPress. There is nothing to configure.

Requires WordPress 6.0+ and PHP 8.0+.

Full notes for the 1.1.0 rebuild are in RELEASE.md.

v1.1.0 — Polished, hardened rebuild

Choose a tag to compare

@SimonHayter SimonHayter released this 09 Sep 21:40

The plugin's behaviour is unchanged for a normal site: the Turnstile script still gets data-cfasync="false". Everything around that has been rebuilt for correctness and maintainability.

Added

  • cftrlf_script_url_fragments filter — change which script URLs are treated as Turnstile.
  • cftrlf_should_bypass_rocket_loader filter — veto the injection per handle.
  • index.php "silence is golden" guards in every plugin directory.
  • .htaccess hardening: directory listing disabled, documentation and data formats denied by name, and a default deny covering any file format added later.
  • Translation support — Text Domain / Domain Path headers and a .pot template.
  • A Documentation link on the Plugins screen row.
  • Developer tooling: composer.json, a PHPCS ruleset targeting WordPress coding standards, .editorconfig, .gitattributes, .distignore, and a GitHub Actions workflow linting PHP 8.0 through 8.4.
  • README.md, RELEASE.md, a WordPress-format readme.txt, and the full GPL-2.0 text.

Changed

  • Restructured into a namespaced Plugin class under includes/, replacing the single global function. The plugin now declares no global functions or constants at all.
  • Injection is now surgical. The previous str_replace( '<script ', … ) rewrote every <script occurrence in the filtered markup, which meant inline before/after scripts attached to the same handle were also rewritten. Only the tag carrying the Turnstile URL is touched now.
  • Whitespace after <script no longer matters. str_replace( '<script ', … ) matched a literal space only, so a tag broken across lines as <script src="…"> by another filter was silently skipped. Matching is now on the tag, not on one whitespace character.
  • The duplicate-attribute guard is quoting-agnostic. It previously looked for the exact string data-cfasync="false", so a tag already carrying data-cfasync='false' or DATA-CFASYNC="false" got a second, conflicting attribute. Any form of the attribute is now detected.
  • Original tag casing is preserved — <SCRIPT> is no longer rewritten to <script>.
  • Matching also accepts challenges.cloudflare.com/turnstile/, so a future v1 API path keeps working without a plugin update.
  • Values returned from public filters are type-checked before use; a third-party callback returning a non-array or non-string can no longer raise a TypeError.
  • Plugin headers corrected. Requires at least and Tested up to previously read 7.1, which is a PHP version — no such WordPress release exists — and would have misreported compatibility to WordPress. They now read 6.0 and 6.8.
  • License header changed from GPL-2.0+ to the SPDX-correct GPL-2.0-or-later, and a License URI added.
  • Plugin renamed from "Cloudflare Turnstile Rocket Loader Bypass" to "Cloudflare Turnstile Rocket Loader Fix".

Security

  • Offline review completed. No dynamic code execution, no filesystem or database writes, no network calls, no superglobal access, no user input handling, and no unescaped output. The one URL rendered in the admin passes through esc_url() and esc_html__().
  • All PHP files exit early unless ABSPATH is defined.

Two issues were found and fixed during that review:

  • Backtracking in the tag pattern. Pathological markup (tens of thousands of <script prefixes, or a 500 KB unterminated tag) exhausted PCRE's JIT stack. The failure was already safe — preg_replace_callback() returns null and the original tag was returned untouched — but every quantifier in the pattern is now possessive, so the match is backtrack-free. A 1 MB tag is processed in under a millisecond with no PCRE error.
  • Unguarded constant on double load. A second copy of the plugin in another directory emitted a Constant already defined warning, because the version constant sat outside the class_exists() guard. All plugin symbols now live on the class, so the single guard covers everything.

Upgrade notes

Drop-in. There are no settings to migrate and no database changes. If you previously copied the 1.0.x function into a theme's functions.php or a snippets plugin, remove it — the duplicate-attribute guard will stop a second injection, but running both is pointless.


Install: download cloudflare-turnstile-rocket-loader-fix-1.1.0.zip below, then Plugins → Add New → Upload Plugin in WordPress. There is nothing to configure.

Requires WordPress 6.0+ and PHP 8.0+.