Back to blog

SQL Injection in WordPress: How Attackers Target Your Database

July 14, 2024·WO Security Shield Team
sql injectiondatabasewordpressvulnerability
SQL Injection in WordPress: How Attackers Target Your Database

SQL injection is consistently ranked among the top web application vulnerabilities and is a key item on the WordPress security checklist. In WordPress, it's most commonly exploited through vulnerable plugin code that passes user input directly to database queries.

How SQL injection works

Consider this vulnerable WordPress plugin code:

// VULNERABLE — never do this
$id = $_GET['product_id'];
$result = $wpdb->query("SELECT * FROM wp_products WHERE id = $id");

An attacker visits:

/shop/?product_id=1 UNION SELECT user_login,user_pass,3,4,5 FROM wp_users--

The query becomes:

SELECT * FROM wp_products WHERE id = 1
UNION SELECT user_login,user_pass,3,4,5 FROM wp_users--

The attacker has just extracted every username and password hash from your WordPress database.

Real-world WordPress SQL injection

Most SQL injection in WordPress today is found in:

  • WooCommerce product queries — parameter-heavy e-commerce queries
  • Custom search functionality — developers often skip sanitisation on search inputs
  • WordPress REST API endpoints — custom endpoints added by plugins
  • Form plugins — Contact Form 7 add-ons, Gravity Forms custom integrations
  • SEO plugins — URL-based parameters fed into database queries

How WO Security Shield blocks SQL injection

WO Security Shield's built-in WAF (Web Application Firewall) inspects every incoming request and blocks SQL injection attempts before they reach your PHP code:

Detected patterns:
  UNION SELECT
  ' OR '1'='1
  information_schema
  ; DROP TABLE
  xp_cmdshell
  SLEEP()
  BENCHMARK()
  LOAD_FILE()

The firewall runs at WordPress init priority 0 — before any plugin or theme code executes — so even vulnerable third-party code is protected.

The correct way to write WordPress database queries

Always use $wpdb->prepare():

// SAFE — parameterised query
$id = (int) $_GET['product_id'];
$result = $wpdb->get_results(
    $wpdb->prepare(
        "SELECT * FROM wp_products WHERE id = %d",
        $id
    )
);

The %d, %s, and %f placeholders ensure values are properly escaped before being inserted into the SQL string.

Checking for SQL injection vulnerabilities

  1. Audit custom database queries — search your theme and custom plugin code for raw $wpdb->query() calls without prepare()
  2. Keep plugins updated — most SQL injection vulnerabilities in the wild are in outdated plugins with known CVEs. Understand the full scope of third-party plugin security risks before installing anything new.
  3. Use WO Security Shield's vulnerability monitor — it checks all your installed plugins and themes against the WordPress.org vulnerability database and alerts you when a CVE is published

WO Security Shield monitors your plugins for known vulnerabilities automatically. Start your free trial today.

Real-World SQL Injection Examples in WordPress

To understand the threat, here are sanitised examples from actual attacks we've observed:

1. Union-Based Injection via Search

An attacker modifies a search query parameter:

?s=test' UNION SELECT user_login,user_pass,3,4,5 FROM wp_users--

If the theme directly outputs search results without proper escaping, this can leak usernames and password hashes. Modern WordPress core sanitises the search parameter, but custom themes that build their own search queries are still vulnerable.

2. Time-Based Blind Injection via Plugin

A vulnerable contact form plugin processes form fields like:

name=John' AND SLEEP(5)--

If the response takes 5 seconds longer than normal, the attacker knows the injection works. They can then extract data one character at a time using conditional SLEEP queries.

3. Second-Order Injection via User Profiles

An attacker registers with a username containing SQL:

admin'--

This username is stored safely. But later, when an admin panel query uses the stored username without re-sanitising it, the injection triggers during a different operation entirely.

How WordPress Core Prevents SQL Injection

WordPress provides $wpdb->prepare() which uses parameterised queries:

// SAFE — parameterised query
$results = $wpdb->get_results(
    $wpdb->prepare(
        "SELECT * FROM {$wpdb->posts} WHERE post_author = %d AND post_status = %s",
        $author_id,
        'publish'
    )
);

// DANGEROUS — string concatenation
$results = $wpdb->get_results(
    "SELECT * FROM {$wpdb->posts} WHERE post_author = " . $_GET['author']
);

The second example is vulnerable because user input is injected directly into the SQL string. Always use $wpdb->prepare().

Protecting Your WordPress Site From SQL Injection

For site owners (non-developers)

  1. Keep plugins updated — most SQL injection vulnerabilities are in plugins, not WordPress core
  2. Use a Web Application Firewall (WAF) — WO Security Shield's firewall detects and blocks SQL injection patterns in request parameters before they reach your database
  3. Remove unused plugins — every plugin is potential attack surface
  4. Monitor your activity log — unusual database errors or slow queries can indicate injection attempts

For developers

  1. Always use $wpdb->prepare() — never concatenate user input into SQL
  2. Validate input types — if you expect an integer, use absint() or intval()
  3. Use WordPress APIsWP_Query, get_posts(), and get_option() handle sanitisation internally
  4. Audit custom queries — search your codebase for $wpdb->query( and $wpdb->get_results( without prepare()

What to Do If You Suspect SQL Injection

If you see signs of SQL injection (unusual database content, new admin users you didn't create, modified options):

  1. Change your database password immediately
  2. Check wp_users for rogue accounts and delete any you don't recognise
  3. Review wp_options for modified siteurl, home, or injected cron entries
  4. Run a file integrity scan — SQL injection is often paired with file-based backdoors for persistent access
  5. Check your plugins against vulnerability databases like WPScan and NIST NVD

SQL injection is serious, but preventable. The combination of updated software, a request firewall, and proper coding practices eliminates the vast majority of attack vectors.

WO Security Shield

Is your WordPress site protected?

Run a free malware scan in under 2 minutes. No credit card required.