CVE-2024-1981 vulnerability and BitFire protection

How BitFire Stops CVE-2024-1981 WPvivid SQL Injection

WordPress vulnerability research

WPvivid exposed its staging workflow to unauthenticated requests and used the attacker-controlled table prefix in database statements, while BitFire blocks automated exploit requests, detects SQL injection, and protects sensitive database outcomes.

Unauthenticated Critical Severity Sensitive Data Exposure SQL Injection
BitFire · Vulnerability advisoryResearch published
AdvisoryCVE-2024-1981
ComponentWPvivid — Backup, Migration & Staging
Relevant sourceincludes/staging/class-wpvivid-staging.php: WPvivid_Staging::load_ajax() and start_staging(); includes/staging/class-wpvivid-staging-copy-db-ex.php: staging SQL construction
Executive summary

What WordPress administrators need to know

CVE-2024-1981 is a critical unauthenticated SQL injection vulnerability identified in WPvivid Backup and Migration version 0.9.68. The plugin registered its staging-start and progress actions for visitors without WordPress accounts. A remote attacker could submit a crafted `table_prefix` POST parameter to the public staging action; vulnerable code stored that value as the new database prefix and later incorporated it into staging SQL statements without safe handling as an identifier. This could let the attacker alter database queries and potentially extract sensitive information. BitFire bot protection rejects unknown automated clients before the staging handler runs, BitFire WAF detects the SQL injection payload at the request boundary, and BitFire PRO RASP independently denies unauthorized sensitive-data access and administrator-account creation at runtime.

At a glance

Key facts

  • The CVE record identifies WPvivid version 0.9.68 as affected
  • No WordPress account is required to call the vulnerable staging-start action
  • The attacker controls the `table_prefix` POST parameter sent to `wpvividstg_start_staging_free`
  • The staging process uses the supplied prefix when constructing database table names and SQL statements
  • BitFire bot protection and WAF stop automated delivery and SQL injection at separate request-layer checks
  • BitFire PRO RASP independently protects sensitive database reads and unauthorized administrator-account creation
01
Vulnerability overview

Understand the exposure

The affected component, attack path, and practical risk for WordPress websites.

Affected componentWPvivid — Backup, Migration & Staging
Potential reach900,000+ installations
Attack techniqueSQL injection
Published2024-02-28
BitFire stops the unknown automated request, rejects SQL syntax in `table_prefix`, and independently protects sensitive database outcomes if vulnerable code is reached.
02
Technical analysis

How the vulnerability works

Research details, affected versions, exploitation behavior, and remediation guidance.

CVE-2024-1981 Exposes WPvivid's Staging Database Workflow

WPvivid provides backup, migration, restore, and staging features to approximately 900,000 WordPress installations. CVE-2024-1981 identifies version 0.9.68 as vulnerable and carries a critical CVSS score of 9.8. An attacker does not need a WordPress account or user interaction: a crafted POST to WordPress's public AJAX endpoint can start the staging process with an attacker-selected `table_prefix`. Because that prefix reaches database statements as SQL structure rather than a safely bound data value, an attacker may alter the intended queries and extract sensitive database information. The precise records exposed or changed depend on the payload and database privileges, so those are possible impacts rather than guaranteed compromise of every site record.

A Public AJAX Hook Carries table_prefix Into SQL

In WPvivid 0.9.68, `WPvivid_Staging::load_ajax()` registers both `wpvividstg_start_staging_free` and `wpvividstg_get_staging_progress_free` with WordPress's `wp_ajax_nopriv_` hooks. Those hooks deliberately dispatch requests from visitors who are not logged in. `start_staging()` reads `table_prefix` directly from `$_POST`, stores it as the staging task's `new_prefix`, and starts copying the site and its database. The database-copy component concatenates that prefix with table names and places the resulting identifiers into statements such as `CREATE TABLE`, `UPDATE`, `DROP TABLE`, and `RENAME TABLE`. Prepared placeholders are designed for data values, not arbitrary SQL identifiers; accepting a caller-selected prefix without a strict identifier allowlist lets SQL metacharacters change the resulting statement.

Version 0.9.69 Removes Unauthenticated Access to the Workflow

The research advisory identifies 0.9.69 as the fixed release, and an exact comparison of the WordPress.org 0.9.68 and 0.9.69 packages confirms the security-relevant change. Version 0.9.69 changes the active hook names from `wp_ajax_nopriv_wpvividstg_start_staging_free` and `wp_ajax_nopriv_wpvividstg_get_staging_progress_free` to their `wp_ajax_` equivalents. Removing the `_nopriv_` portion from each active registration makes WordPress dispatch those endpoints only for authenticated requests. The correction closes the exposed route rather than attempting to make hostile table-prefix syntax safe. The corrected-behavior excerpt presents that hook-name change directly as an abridged reconstruction instead of showing commented-out registrations.

BitFire Blocks Automated Delivery and the SQL Injection Payload

Exploitation requires an attacker-controlled POST containing staging parameters such as `action` and `table_prefix`. BitFire bot protection detects an unknown automated client or impersonated browser sending unknown GET or POST parameters and can reject it before WordPress routes the request to WPvivid. Independently, BitFire WAF analyzes the `table_prefix` value for SQL injection behavior, including malicious SQL syntax and evasion patterns. When that rule matches, the WAF denies the request before `start_staging()` stores the hostile prefix or the staging task assembles a database statement. These request controls are behavior-based and active before a CVE-specific signature exists; they do not claim to block legitimate explicitly allowed integrations.

BitFire PRO RASP Protects the Database Outcome

BitFire PRO RASP provides a separate runtime boundary for exploit paths that reach application code despite request filtering. Its database policies prevent unauthorized access to sensitive data and unauthorized creation of WordPress administrator accounts. If an injected staging query attempts either outcome, RASP follows execution to the protected database operation and denies it even though the plugin accepted and routed the request incorrectly. This outcome-based control does not replace SQL injection filtering and does not imply that every injected statement creates an administrator; it limits the high-impact results that a successful injection may pursue from any request vector.

Conclusion: Staging Operations Need Independent Access Controls

Administrators can verify the installed WPvivid release and review web, database, staging, and BitFire events for unexpected `wpvividstg_start_staging_free` requests, unusual table prefixes, or unrecognized staging tasks. CVE-2024-1981 demonstrates why site administrators need a security solution with built-in access controls and zero-day protection when a plugin exposes a privileged database workflow. BitFire's bot and SQLi controls can stop the malicious request before WPvivid runs, while BitFire PRO RASP independently protects sensitive reads and administrator creation at the operation where they must succeed—even before a vulnerability-specific response has been written.

03
Source review

Vulnerable and fixed code

The relevant source is located in includes/staging/class-wpvivid-staging.php: WPvivid_Staging::load_ajax() and start_staging(); includes/staging/class-wpvivid-staging-copy-db-ex.php: staging SQL construction.

BeforeVulnerable behavior
// Vulnerable registration behavior, abridged from WPvivid 0.9.68.
public function load_ajax()
{
    add_action('wp_ajax_nopriv_wpvividstg_start_staging_free', array($this, 'start_staging'));
    add_action('wp_ajax_nopriv_wpvividstg_get_staging_progress_free', array($this, 'get_staging_progress'));
}
AfterCorrected behavior
// Corrected registration behavior, abridged reconstruction.
public function load_ajax()
{
    add_action('wp_ajax_wpvividstg_start_staging_free', array($this, 'start_staging'));
    add_action('wp_ajax_wpvividstg_get_staging_progress_free', array($this, 'get_staging_progress'));
}
04
Zero-day protection

Protection from the first exploit request

BitFire protects WordPress servers on day zero—before a vulnerability is publicly known and before other vendors have time to develop signatures or patches.

01 · VerifyStop unknown clients

Bot controls and browser verification stop untrusted automated clients before previously unknown exploit code reaches WordPress.

02 · DetectBlock malicious behavior

General WAF protections identify dangerous request behavior and hostile payloads without waiting for a vulnerability-specific signature.

03 · PreventContain attacks at runtime

RASP follows execution inside PHP and prevents unauthorized changes to protected files, accounts, and database content.

BitFire · WordPress protectionZero-day ready
BitFire zero-day WordPress vulnerability protection
BitFire combines verified-client controls, behavior-based WAF detection, and runtime RASP enforcement to protect WordPress before an exploit has a name, CVE, signature, or vendor patch.
About the author

Cory Marsh

Cory has more than 20 years of internet security experience and is a lead developer on the BitFire project.

Read BitFire security research →
Protect your WordPress website

Add protection before the next exploit arrives.

BitFire combines bot controls, request inspection, malware detection, and runtime protection in one WordPress security platform.

Protect my site free →