
PoC of CVE-2025-22783
WordPress plugin
Component name SEO Plugin by Squirrly SEO
Vulnerable version <= 12.4.01
Component slug squirrly-seo
Component link https://wordpress.org/plugins/squirrly-seo/
Vulnerability class A3: Injection
Vulnerability type SQL Injection
Contributor +
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.
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.
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
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
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.

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:
$search contains the search term entered during internal link search, and the sanitize_text_field function is used to process the user input data.$search is used as part of the conditional clause and stored in the variable $query_where.$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.
⚠️ 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.

Next, enter the following command to run the PoC code.
Required modulerequests
python poc.py
