Goal Reached Thanks to every supporter — we hit 100%!

Goal: 1000 CNY · Raised: 1000 CNY

100.0%

CVE-2025-22783 PoC — WordPress plugin SEO Plugin by Squirrly SEO SQL注入漏洞

Source
Associated Vulnerability
Title:WordPress plugin SEO Plugin by Squirrly SEO SQL注入漏洞 (CVE-2025-22783)
Description:WordPress和WordPress plugin都是WordPress基金会的产品。WordPress是一套使用PHP语言开发的博客平台。该平台支持在PHP和MySQL的服务器上架设个人博客网站。WordPress plugin是一个应用插件。 WordPress plugin SEO Plugin by Squirrly SEO 12.4.03及之前版本存在SQL注入漏洞,该漏洞源于特殊元素中和不当,可能导致SQL注入。
Description
PoC of CVE-2025-22783
Readme
# CVE-2025-22783

## 1️⃣ Component type

WordPress plugin

## 2️⃣ Component details

`Component name` SEO Plugin by Squirrly SEO

`Vulnerable version` <= 12.4.01

`Component slug` squirrly-seo

`Component link` [https://wordpress.org/plugins/squirrly-seo/](https://wordpress.org/plugins/squirrly-seo/)

## 3️⃣ OWASP 2017: TOP 10

`Vulnerability class` A3: Injection

`Vulnerability type` SQL Injection

## 4️⃣ Pre-requisite

Contributor +

## 5️⃣ **Vulnerability details**

### 👉 **Short description**

The SEO Plugin by Squirrly SEO allows you to improve your website's SEO through an internal linking feature that lets you select source and target pages based on specific keywords. You can manage each link's keywords, source pages, target pages, and status through the internal links management page (`/wp-admin/admin.php?page=sq_focuspages&tab=innerlinks`).

In versions 12.4.01 and below of the Squirrly SEO plugin, you can search for created internal links on the internal links management page. A SQL Injection vulnerability occurs when search terms entered by users (Contributor+) are passed directly to database queries without validation.

While search results are not directly displayed on the internal links management page, database information can be extracted using Time-based SQL Injection techniques such as the SLEEP function.

### 👉 **How to reproduce (PoC)**

1. Log in to the target site with an account that has Contributor or higher privileges where Squirrly SEO plugin version 12.4.01 or lower is installed.
2. Then, when you access the URL below, since the IF statement condition '1=1' in the SQL Injection payload is always true, the `SLEEP(5)` function will execute and the page will load after 5 seconds.
    
    ```
    http://localhost:8080/wp-admin/admin.php?page=sq_focuspages&tab=innerlinks&stype&squery='+AND+1%3D2)+UNION+SELECT+(IF(1=1,SLEEP(5),1)),2,3,4,5,6,7%23
    ```
    
3. On the other hand, if you change the IF statement condition to '1=2', the page will load immediately because the result value is false.
    
    ```
    http://localhost:8080/wp-admin/admin.php?page=sq_focuspages&tab=innerlinks&stype&squery='+AND+1%3D2)+UNION+SELECT+(IF(1=2,SLEEP(5),1)),2,3,4,5,6,7%23
    ```
    

### 👉 **Additional information (optional)**

### [Root Cause of Vulnerability]

On the internal links management page (`/wp-admin/admin.php?page=sq_focuspages&tab=innerlinks`) of the Squirrly SEO plugin, when searching for internal links, it queries the database by calling the `getSqInnerlinks` function in the `/wp-content/plugins/squirrly-seo/models/Qss.php` file.

![image](images/image-001.png)

At this point, we can see that the variable `$query_where` is directly inserted into the SQL query. Let's examine how the value of variable `$query_where` is constructed:

1. line 75: The variable `$search` contains the search term entered during internal link search, and the `sanitize_text_field` function is used to process the user input data.
2. line 76: Subsequently, the variable `$search` is used as part of the conditional clause and stored in the variable `$query_where`.
3. line 79 ~ line 80: Additional conditions are added to the variable `$query_where`, and filters are applied through the `apply_filters` function.

Therefore, while the search term entered by users during internal link search is processed by the `sanitize_text_field` function, this function cannot prevent SQL Injection attacks. Special characters used in SQL queries (single quotes (`'`), comments (`#`), etc.) are not filtered, and when the variable `$search` containing SQL Injection payload is passed to the database query without proper escaping, an SQL Injection vulnerability occurs.

### [PoC Code Implementation and Execution]

> ⚠️ The implemented PoC code logs in with an administrator account to create an account with minimal privileges (Contributor+) required for vulnerability reproduction, and then triggers the vulnerability using that account.
>


1. Open the PoC code in an editor and enter the WordPress site address and administrator credentials.

![image](images/image-002.png)

2. Next, enter the following command to run the PoC code.
    
    > `Required module`  requests
    > 
    
    ```bash
    python poc.py
    ```    
    ![image](images/image-003.png)

## 6️⃣ Exploit Demo

[![video](https://img.youtube.com/vi/6EsYS0XxoqY/0.jpg)](https://www.youtube.com/watch?v=6EsYS0XxoqY)

## 7️⃣ References
- [https://nvd.nist.gov/vuln/detail/CVE-2025-22783](https://nvd.nist.gov/vuln/detail/CVE-2025-22783)
File Snapshot

[4.0K] /data/pocs/2221d508521323035a9452af2b5cf67dabe3b705 ├── [4.0K] images │   ├── [920K] image-001.png │   ├── [480K] image-002.png │   └── [459K] image-003.png ├── [4.8K] poc.py └── [4.5K] README.md 1 directory, 5 files
Shenlong Bot has cached this for you
Remarks
    1. It is advised to access via the original source first.
    2. If the original source is unavailable, please email f.jinxu#gmail.com for a local snapshot (replace # with @).
    3. Shenlong has snapshotted the POC code for you. To support long-term maintenance, please consider donating. Thank you for your support.