Elementor Ally plugin SQL injection (CVE-2026-2413) leaves 250k+ WordPress sites exposed

Unauthenticated time-based SQLi in the Ally accessibility plugin (up to 4.0.3) is fixed in 4.1.0, but about 64% of 400k sites hadn't updated. Patch and check.

TechLogHub Engineering Team
March 11, 2026
3 min read
0 views

Share Article

SQLi flaw in Elementor Ally plugin impacts 250k+ WordPress sites

Elementor's Ally accessibility plugin, installed on more than 400,000 WordPress sites, had an unauthenticated SQL injection flaw in versions up to 4.0.3. A fix shipped in February, but weeks later only about a third of sites had applied it. The bug comes from a common mistake: treating a URL-sanitizing function as if it were SQL escaping. Anyone who writes PHP against $wpdb should learn from it.

What happened

Drew Webber (mcdruid), an offensive security engineer at Acquia, reported the flaw through Wordfence's bug bounty program, and Wordfence validated it. It's tracked as CVE-2026-2413 (CVSS 3.1 score 7.5, High; CWE-89). Some earlier reports gave the number as CVE-2026-2313, which is wrong. The timeline:

  • 13 February 2026. Vendor notified.
  • 23 February 2026. Ally 4.1.0 released with the fix.
  • 11 March 2026. CVE published. Webber received an $800 bounty.

By then WordPress.org data showed about 36% of Ally installations on 4.1.0, which left more than 250,000 sites running vulnerable versions.

Who is affected

  • Sites running Ally - Web Accessibility & Usability (WordPress.org slug pojo-accessibility) version 4.0.3 or earlier.
  • Exploitation requires the plugin to be connected to an Elementor account with the Remediation module active. Sites that installed Ally but never connected it aren't exploitable through this path.
  • Agencies and hosts that manage many WordPress installs, where plugin updates often wait for scheduled maintenance.

What it means for developers and engineering teams

The bug is in get_global_remediations(). A URL value supplied by the user went through esc_url_raw() and was then concatenated into a SQL JOIN clause. esc_url_raw() makes a string safe to use as a URL. It doesn't neutralise quotes or other SQL metacharacters in a way that makes the string safe inside a query. An attacker could therefore extend the query and use time-based blind techniques, such as conditional SLEEP() calls, to extract data one bit at a time. That includes user records and password hashes stored in the database.

Two details make this bug worse than its CVSS score suggests. First, the injection point is reachable without logging in, so automated scanners can find it at scale once a proof of concept circulates. Second, time-based blind extraction is slow but reliable. It needs no error messages or visible output, so hardened error handling doesn't stop it. A WAF that rate-limits or flags long-running requests helps, but it doesn't replace the patch.

The rule is simple: sanitise for the context where the value is used. In WordPress, anything that reaches SQL goes through $wpdb->prepare() with placeholders, wherever else it has been cleaned:

// Vulnerable pattern
$url = esc_url_raw( $_GET['url'] );
$sql = "SELECT ... JOIN {$table} r ON r.url = '{$url}'";

// Safe pattern
$url = esc_url_raw( wp_unslash( $_GET['url'] ) );
$sql = $wpdb->prepare(
    "SELECT ... JOIN {$table} r ON r.url = %s",
    $url
);

Static analysis catches this class of bug well. PHPCS with the WordPress Coding Standards flags unprepared queries (WordPress.DB.PreparedSQL), and it's worth running in CI for any plugin or theme you maintain.

What to do now

  • Update Ally to 4.1.0 or later. With WP-CLI:
    wp plugin list --name=pojo-accessibility --fields=name,status,version
    wp plugin update pojo-accessibility
  • Update WordPress core. Version 6.9.2, released around the same time, fixed 10 vulnerabilities including XSS, an authorization bypass and SSRF.
  • Turn on automatic updates for low-risk plugins like accessibility widgets, or put managed sites on a weekly patch cadence.
  • Check for signs of exploitation: unusually slow requests carrying the remediation URL parameter in access logs, and new or changed admin accounts.
  • Rotate admin passwords and salts if you ran a vulnerable, connected version on a public site.
  • Add $wpdb->prepare() checks to code review and CI for your own plugins, for example with phpcs --standard=WordPress.
  • Audit other plugins that take URLs as input. Accessibility, SEO and redirect plugins all handle page URLs, and the same esc_url_raw()-then-concatenate mistake can turn up anywhere.

Related on TechLogHub

Sources

Stay Updated

Get the next deep dive in your inbox

Subscribe for product analysis, engineering explainers, and practical guides published on TechLogHub.

See what launched this week

One email a week: new and trending developer tools, fresh comparisons, and what shipped. Unsubscribe in one click.